xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fUniformApiTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.0 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Uniform API tests.
22*35238bceSAndroid Build Coastguard Worker  *
23*35238bceSAndroid Build Coastguard Worker  * \todo [2013-02-26 nuutti] Much duplication between this and ES2.
24*35238bceSAndroid Build Coastguard Worker  *                             Utilities to glshared?
25*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
26*35238bceSAndroid Build Coastguard Worker 
27*35238bceSAndroid Build Coastguard Worker #include "es3fUniformApiTests.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluCallLogWrapper.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluVarType.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluTextureUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluTexture.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "tcuCommandLine.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "deString.h"
41*35238bceSAndroid Build Coastguard Worker #include "deSharedPtr.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
45*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
46*35238bceSAndroid Build Coastguard Worker 
47*35238bceSAndroid Build Coastguard Worker #include <set>
48*35238bceSAndroid Build Coastguard Worker #include <cstring>
49*35238bceSAndroid Build Coastguard Worker 
50*35238bceSAndroid Build Coastguard Worker using namespace glw;
51*35238bceSAndroid Build Coastguard Worker 
52*35238bceSAndroid Build Coastguard Worker namespace deqp
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker namespace gles3
55*35238bceSAndroid Build Coastguard Worker {
56*35238bceSAndroid Build Coastguard Worker namespace Functional
57*35238bceSAndroid Build Coastguard Worker {
58*35238bceSAndroid Build Coastguard Worker 
59*35238bceSAndroid Build Coastguard Worker using de::Random;
60*35238bceSAndroid Build Coastguard Worker using de::SharedPtr;
61*35238bceSAndroid Build Coastguard Worker using glu::ShaderProgram;
62*35238bceSAndroid Build Coastguard Worker using glu::StructType;
63*35238bceSAndroid Build Coastguard Worker using std::string;
64*35238bceSAndroid Build Coastguard Worker using std::vector;
65*35238bceSAndroid Build Coastguard Worker using tcu::ScopedLogSection;
66*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
67*35238bceSAndroid Build Coastguard Worker 
68*35238bceSAndroid Build Coastguard Worker typedef bool (*dataTypePredicate)(glu::DataType);
69*35238bceSAndroid Build Coastguard Worker 
70*35238bceSAndroid Build Coastguard Worker static const int MAX_RENDER_WIDTH         = 32;
71*35238bceSAndroid Build Coastguard Worker static const int MAX_RENDER_HEIGHT        = 32;
72*35238bceSAndroid Build Coastguard Worker static const int MAX_NUM_SAMPLER_UNIFORMS = 16;
73*35238bceSAndroid Build Coastguard Worker 
74*35238bceSAndroid Build Coastguard Worker static const glu::DataType s_testDataTypes[] = {
75*35238bceSAndroid Build Coastguard Worker     glu::TYPE_FLOAT,      glu::TYPE_FLOAT_VEC2,   glu::TYPE_FLOAT_VEC3,   glu::TYPE_FLOAT_VEC4,
76*35238bceSAndroid Build Coastguard Worker     glu::TYPE_FLOAT_MAT2, glu::TYPE_FLOAT_MAT2X3, glu::TYPE_FLOAT_MAT2X4, glu::TYPE_FLOAT_MAT3X2,
77*35238bceSAndroid Build Coastguard Worker     glu::TYPE_FLOAT_MAT3, glu::TYPE_FLOAT_MAT3X4, glu::TYPE_FLOAT_MAT4X2, glu::TYPE_FLOAT_MAT4X3,
78*35238bceSAndroid Build Coastguard Worker     glu::TYPE_FLOAT_MAT4,
79*35238bceSAndroid Build Coastguard Worker 
80*35238bceSAndroid Build Coastguard Worker     glu::TYPE_INT,        glu::TYPE_INT_VEC2,     glu::TYPE_INT_VEC3,     glu::TYPE_INT_VEC4,
81*35238bceSAndroid Build Coastguard Worker 
82*35238bceSAndroid Build Coastguard Worker     glu::TYPE_UINT,       glu::TYPE_UINT_VEC2,    glu::TYPE_UINT_VEC3,    glu::TYPE_UINT_VEC4,
83*35238bceSAndroid Build Coastguard Worker 
84*35238bceSAndroid Build Coastguard Worker     glu::TYPE_BOOL,       glu::TYPE_BOOL_VEC2,    glu::TYPE_BOOL_VEC3,    glu::TYPE_BOOL_VEC4,
85*35238bceSAndroid Build Coastguard Worker 
86*35238bceSAndroid Build Coastguard Worker     glu::TYPE_SAMPLER_2D, glu::TYPE_SAMPLER_CUBE
87*35238bceSAndroid Build Coastguard Worker     // \note We don't test all sampler types here.
88*35238bceSAndroid Build Coastguard Worker };
89*35238bceSAndroid Build Coastguard Worker 
getGLInt(const glw::Functions & funcs,const uint32_t name)90*35238bceSAndroid Build Coastguard Worker static inline int getGLInt(const glw::Functions &funcs, const uint32_t name)
91*35238bceSAndroid Build Coastguard Worker {
92*35238bceSAndroid Build Coastguard Worker     int val = -1;
93*35238bceSAndroid Build Coastguard Worker     funcs.getIntegerv(name, &val);
94*35238bceSAndroid Build Coastguard Worker     return val;
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker 
vec4FromPtr(const float * const ptr)97*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 vec4FromPtr(const float *const ptr)
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 result;
100*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < 4; i++)
101*35238bceSAndroid Build Coastguard Worker         result[i] = ptr[i];
102*35238bceSAndroid Build Coastguard Worker     return result;
103*35238bceSAndroid Build Coastguard Worker }
104*35238bceSAndroid Build Coastguard Worker 
beforeLast(const string & str,const char c)105*35238bceSAndroid Build Coastguard Worker static inline string beforeLast(const string &str, const char c)
106*35238bceSAndroid Build Coastguard Worker {
107*35238bceSAndroid Build Coastguard Worker     return str.substr(0, str.find_last_of(c));
108*35238bceSAndroid Build Coastguard Worker }
109*35238bceSAndroid Build Coastguard Worker 
fillWithColor(const tcu::PixelBufferAccess & access,const tcu::Vec4 & color)110*35238bceSAndroid Build Coastguard Worker static inline void fillWithColor(const tcu::PixelBufferAccess &access, const tcu::Vec4 &color)
111*35238bceSAndroid Build Coastguard Worker {
112*35238bceSAndroid Build Coastguard Worker     for (int z = 0; z < access.getDepth(); z++)
113*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < access.getHeight(); y++)
114*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < access.getWidth(); x++)
115*35238bceSAndroid Build Coastguard Worker                 access.setPixel(color, x, y, z);
116*35238bceSAndroid Build Coastguard Worker }
117*35238bceSAndroid Build Coastguard Worker 
getSamplerNumLookupDimensions(const glu::DataType type)118*35238bceSAndroid Build Coastguard Worker static inline int getSamplerNumLookupDimensions(const glu::DataType type)
119*35238bceSAndroid Build Coastguard Worker {
120*35238bceSAndroid Build Coastguard Worker     switch (type)
121*35238bceSAndroid Build Coastguard Worker     {
122*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D:
123*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_2D:
124*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_2D:
125*35238bceSAndroid Build Coastguard Worker         return 2;
126*35238bceSAndroid Build Coastguard Worker 
127*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_3D:
128*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_3D:
129*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_3D:
130*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D_SHADOW:
131*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D_ARRAY:
132*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_2D_ARRAY:
133*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
134*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_CUBE:
135*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_CUBE:
136*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_CUBE:
137*35238bceSAndroid Build Coastguard Worker         return 3;
138*35238bceSAndroid Build Coastguard Worker 
139*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_CUBE_SHADOW:
140*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
141*35238bceSAndroid Build Coastguard Worker         return 4;
142*35238bceSAndroid Build Coastguard Worker 
143*35238bceSAndroid Build Coastguard Worker     default:
144*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
145*35238bceSAndroid Build Coastguard Worker         return 0;
146*35238bceSAndroid Build Coastguard Worker     }
147*35238bceSAndroid Build Coastguard Worker }
148*35238bceSAndroid Build Coastguard Worker 
getSamplerLookupReturnType(const glu::DataType type)149*35238bceSAndroid Build Coastguard Worker static inline glu::DataType getSamplerLookupReturnType(const glu::DataType type)
150*35238bceSAndroid Build Coastguard Worker {
151*35238bceSAndroid Build Coastguard Worker     switch (type)
152*35238bceSAndroid Build Coastguard Worker     {
153*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D:
154*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_CUBE:
155*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D_ARRAY:
156*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_3D:
157*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_FLOAT_VEC4;
158*35238bceSAndroid Build Coastguard Worker 
159*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_2D:
160*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_CUBE:
161*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
162*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_3D:
163*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_UINT_VEC4;
164*35238bceSAndroid Build Coastguard Worker 
165*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_2D:
166*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_CUBE:
167*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_2D_ARRAY:
168*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_3D:
169*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_INT_VEC4;
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D_SHADOW:
172*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_CUBE_SHADOW:
173*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
174*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_FLOAT;
175*35238bceSAndroid Build Coastguard Worker 
176*35238bceSAndroid Build Coastguard Worker     default:
177*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
178*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_LAST;
179*35238bceSAndroid Build Coastguard Worker     }
180*35238bceSAndroid Build Coastguard Worker }
181*35238bceSAndroid Build Coastguard Worker 
182*35238bceSAndroid Build Coastguard Worker template <glu::DataType T>
dataTypeEquals(const glu::DataType t)183*35238bceSAndroid Build Coastguard Worker static bool dataTypeEquals(const glu::DataType t)
184*35238bceSAndroid Build Coastguard Worker {
185*35238bceSAndroid Build Coastguard Worker     return t == T;
186*35238bceSAndroid Build Coastguard Worker }
187*35238bceSAndroid Build Coastguard Worker 
188*35238bceSAndroid Build Coastguard Worker template <int N>
dataTypeIsMatrixWithNRows(const glu::DataType t)189*35238bceSAndroid Build Coastguard Worker static bool dataTypeIsMatrixWithNRows(const glu::DataType t)
190*35238bceSAndroid Build Coastguard Worker {
191*35238bceSAndroid Build Coastguard Worker     return glu::isDataTypeMatrix(t) && glu::getDataTypeMatrixNumRows(t) == N;
192*35238bceSAndroid Build Coastguard Worker }
193*35238bceSAndroid Build Coastguard Worker 
typeContainsMatchingBasicType(const glu::VarType & type,const dataTypePredicate predicate)194*35238bceSAndroid Build Coastguard Worker static bool typeContainsMatchingBasicType(const glu::VarType &type, const dataTypePredicate predicate)
195*35238bceSAndroid Build Coastguard Worker {
196*35238bceSAndroid Build Coastguard Worker     if (type.isBasicType())
197*35238bceSAndroid Build Coastguard Worker         return predicate(type.getBasicType());
198*35238bceSAndroid Build Coastguard Worker     else if (type.isArrayType())
199*35238bceSAndroid Build Coastguard Worker         return typeContainsMatchingBasicType(type.getElementType(), predicate);
200*35238bceSAndroid Build Coastguard Worker     else
201*35238bceSAndroid Build Coastguard Worker     {
202*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(type.isStructType());
203*35238bceSAndroid Build Coastguard Worker         const StructType &structType = *type.getStructPtr();
204*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < structType.getNumMembers(); i++)
205*35238bceSAndroid Build Coastguard Worker             if (typeContainsMatchingBasicType(structType.getMember(i).getType(), predicate))
206*35238bceSAndroid Build Coastguard Worker                 return true;
207*35238bceSAndroid Build Coastguard Worker         return false;
208*35238bceSAndroid Build Coastguard Worker     }
209*35238bceSAndroid Build Coastguard Worker }
210*35238bceSAndroid Build Coastguard Worker 
getDistinctSamplerTypes(vector<glu::DataType> & dst,const glu::VarType & type)211*35238bceSAndroid Build Coastguard Worker static void getDistinctSamplerTypes(vector<glu::DataType> &dst, const glu::VarType &type)
212*35238bceSAndroid Build Coastguard Worker {
213*35238bceSAndroid Build Coastguard Worker     if (type.isBasicType())
214*35238bceSAndroid Build Coastguard Worker     {
215*35238bceSAndroid Build Coastguard Worker         const glu::DataType basicType = type.getBasicType();
216*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeSampler(basicType) && std::find(dst.begin(), dst.end(), basicType) == dst.end())
217*35238bceSAndroid Build Coastguard Worker             dst.push_back(basicType);
218*35238bceSAndroid Build Coastguard Worker     }
219*35238bceSAndroid Build Coastguard Worker     else if (type.isArrayType())
220*35238bceSAndroid Build Coastguard Worker         getDistinctSamplerTypes(dst, type.getElementType());
221*35238bceSAndroid Build Coastguard Worker     else
222*35238bceSAndroid Build Coastguard Worker     {
223*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(type.isStructType());
224*35238bceSAndroid Build Coastguard Worker         const StructType &structType = *type.getStructPtr();
225*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < structType.getNumMembers(); i++)
226*35238bceSAndroid Build Coastguard Worker             getDistinctSamplerTypes(dst, structType.getMember(i).getType());
227*35238bceSAndroid Build Coastguard Worker     }
228*35238bceSAndroid Build Coastguard Worker }
229*35238bceSAndroid Build Coastguard Worker 
getNumSamplersInType(const glu::VarType & type)230*35238bceSAndroid Build Coastguard Worker static int getNumSamplersInType(const glu::VarType &type)
231*35238bceSAndroid Build Coastguard Worker {
232*35238bceSAndroid Build Coastguard Worker     if (type.isBasicType())
233*35238bceSAndroid Build Coastguard Worker         return glu::isDataTypeSampler(type.getBasicType()) ? 1 : 0;
234*35238bceSAndroid Build Coastguard Worker     else if (type.isArrayType())
235*35238bceSAndroid Build Coastguard Worker         return getNumSamplersInType(type.getElementType()) * type.getArraySize();
236*35238bceSAndroid Build Coastguard Worker     else
237*35238bceSAndroid Build Coastguard Worker     {
238*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(type.isStructType());
239*35238bceSAndroid Build Coastguard Worker         const StructType &structType = *type.getStructPtr();
240*35238bceSAndroid Build Coastguard Worker         int sum                      = 0;
241*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < structType.getNumMembers(); i++)
242*35238bceSAndroid Build Coastguard Worker             sum += getNumSamplersInType(structType.getMember(i).getType());
243*35238bceSAndroid Build Coastguard Worker         return sum;
244*35238bceSAndroid Build Coastguard Worker     }
245*35238bceSAndroid Build Coastguard Worker }
246*35238bceSAndroid Build Coastguard Worker 
generateRandomType(const int maxDepth,int & curStructIdx,vector<const StructType * > & structTypesDst,Random & rnd)247*35238bceSAndroid Build Coastguard Worker static glu::VarType generateRandomType(const int maxDepth, int &curStructIdx,
248*35238bceSAndroid Build Coastguard Worker                                        vector<const StructType *> &structTypesDst, Random &rnd)
249*35238bceSAndroid Build Coastguard Worker {
250*35238bceSAndroid Build Coastguard Worker     const bool isStruct = maxDepth > 0 && rnd.getFloat() < 0.2f;
251*35238bceSAndroid Build Coastguard Worker     const bool isArray  = rnd.getFloat() < 0.3f;
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker     if (isStruct)
254*35238bceSAndroid Build Coastguard Worker     {
255*35238bceSAndroid Build Coastguard Worker         const int numMembers         = rnd.getInt(1, 5);
256*35238bceSAndroid Build Coastguard Worker         StructType *const structType = new StructType(("structType" + de::toString(curStructIdx++)).c_str());
257*35238bceSAndroid Build Coastguard Worker 
258*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numMembers; i++)
259*35238bceSAndroid Build Coastguard Worker             structType->addMember(("m" + de::toString(i)).c_str(),
260*35238bceSAndroid Build Coastguard Worker                                   generateRandomType(maxDepth - 1, curStructIdx, structTypesDst, rnd));
261*35238bceSAndroid Build Coastguard Worker 
262*35238bceSAndroid Build Coastguard Worker         structTypesDst.push_back(structType);
263*35238bceSAndroid Build Coastguard Worker         return isArray ? glu::VarType(glu::VarType(structType), rnd.getInt(1, 5)) : glu::VarType(structType);
264*35238bceSAndroid Build Coastguard Worker     }
265*35238bceSAndroid Build Coastguard Worker     else
266*35238bceSAndroid Build Coastguard Worker     {
267*35238bceSAndroid Build Coastguard Worker         const glu::DataType basicType =
268*35238bceSAndroid Build Coastguard Worker             (glu::DataType)s_testDataTypes[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testDataTypes) - 1)];
269*35238bceSAndroid Build Coastguard Worker         const glu::Precision precision =
270*35238bceSAndroid Build Coastguard Worker             glu::isDataTypeBoolOrBVec(basicType) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
271*35238bceSAndroid Build Coastguard Worker         return isArray ? glu::VarType(glu::VarType(basicType, precision), rnd.getInt(1, 5)) :
272*35238bceSAndroid Build Coastguard Worker                          glu::VarType(basicType, precision);
273*35238bceSAndroid Build Coastguard Worker     }
274*35238bceSAndroid Build Coastguard Worker }
275*35238bceSAndroid Build Coastguard Worker 
276*35238bceSAndroid Build Coastguard Worker namespace
277*35238bceSAndroid Build Coastguard Worker {
278*35238bceSAndroid Build Coastguard Worker 
279*35238bceSAndroid Build Coastguard Worker struct VarValue
280*35238bceSAndroid Build Coastguard Worker {
281*35238bceSAndroid Build Coastguard Worker     glu::DataType type;
282*35238bceSAndroid Build Coastguard Worker 
283*35238bceSAndroid Build Coastguard Worker     union
284*35238bceSAndroid Build Coastguard Worker     {
285*35238bceSAndroid Build Coastguard Worker         float floatV[4 * 4]; // At most mat4. \note Matrices here are column-major.
286*35238bceSAndroid Build Coastguard Worker         int32_t intV[4];
287*35238bceSAndroid Build Coastguard Worker         uint32_t uintV[4];
288*35238bceSAndroid Build Coastguard Worker         bool boolV[4];
289*35238bceSAndroid Build Coastguard Worker         struct
290*35238bceSAndroid Build Coastguard Worker         {
291*35238bceSAndroid Build Coastguard Worker             int unit;
292*35238bceSAndroid Build Coastguard Worker             union
293*35238bceSAndroid Build Coastguard Worker             {
294*35238bceSAndroid Build Coastguard Worker                 float floatV[4];
295*35238bceSAndroid Build Coastguard Worker                 int32_t intV[4];
296*35238bceSAndroid Build Coastguard Worker                 uint32_t uintV[4];
297*35238bceSAndroid Build Coastguard Worker             } fillColor;
298*35238bceSAndroid Build Coastguard Worker         } samplerV;
299*35238bceSAndroid Build Coastguard Worker     } val;
300*35238bceSAndroid Build Coastguard Worker };
301*35238bceSAndroid Build Coastguard Worker 
302*35238bceSAndroid Build Coastguard Worker enum CaseShaderType
303*35238bceSAndroid Build Coastguard Worker {
304*35238bceSAndroid Build Coastguard Worker     CASESHADERTYPE_VERTEX = 0,
305*35238bceSAndroid Build Coastguard Worker     CASESHADERTYPE_FRAGMENT,
306*35238bceSAndroid Build Coastguard Worker     CASESHADERTYPE_BOTH,
307*35238bceSAndroid Build Coastguard Worker 
308*35238bceSAndroid Build Coastguard Worker     CASESHADERTYPE_LAST
309*35238bceSAndroid Build Coastguard Worker };
310*35238bceSAndroid Build Coastguard Worker 
311*35238bceSAndroid Build Coastguard Worker struct Uniform
312*35238bceSAndroid Build Coastguard Worker {
313*35238bceSAndroid Build Coastguard Worker     string name;
314*35238bceSAndroid Build Coastguard Worker     glu::VarType type;
315*35238bceSAndroid Build Coastguard Worker 
Uniformdeqp::gles3::Functional::__anondef265660111::Uniform316*35238bceSAndroid Build Coastguard Worker     Uniform(const char *const name_, const glu::VarType &type_) : name(name_), type(type_)
317*35238bceSAndroid Build Coastguard Worker     {
318*35238bceSAndroid Build Coastguard Worker     }
319*35238bceSAndroid Build Coastguard Worker };
320*35238bceSAndroid Build Coastguard Worker 
321*35238bceSAndroid Build Coastguard Worker // A set of uniforms, along with related struct types.
322*35238bceSAndroid Build Coastguard Worker class UniformCollection
323*35238bceSAndroid Build Coastguard Worker {
324*35238bceSAndroid Build Coastguard Worker public:
getNumUniforms(void) const325*35238bceSAndroid Build Coastguard Worker     int getNumUniforms(void) const
326*35238bceSAndroid Build Coastguard Worker     {
327*35238bceSAndroid Build Coastguard Worker         return (int)m_uniforms.size();
328*35238bceSAndroid Build Coastguard Worker     }
getNumStructTypes(void) const329*35238bceSAndroid Build Coastguard Worker     int getNumStructTypes(void) const
330*35238bceSAndroid Build Coastguard Worker     {
331*35238bceSAndroid Build Coastguard Worker         return (int)m_structTypes.size();
332*35238bceSAndroid Build Coastguard Worker     }
getUniform(const int ndx)333*35238bceSAndroid Build Coastguard Worker     Uniform &getUniform(const int ndx)
334*35238bceSAndroid Build Coastguard Worker     {
335*35238bceSAndroid Build Coastguard Worker         return m_uniforms[ndx];
336*35238bceSAndroid Build Coastguard Worker     }
getUniform(const int ndx) const337*35238bceSAndroid Build Coastguard Worker     const Uniform &getUniform(const int ndx) const
338*35238bceSAndroid Build Coastguard Worker     {
339*35238bceSAndroid Build Coastguard Worker         return m_uniforms[ndx];
340*35238bceSAndroid Build Coastguard Worker     }
getStructType(const int ndx) const341*35238bceSAndroid Build Coastguard Worker     const StructType *getStructType(const int ndx) const
342*35238bceSAndroid Build Coastguard Worker     {
343*35238bceSAndroid Build Coastguard Worker         return m_structTypes[ndx];
344*35238bceSAndroid Build Coastguard Worker     }
addUniform(const Uniform & uniform)345*35238bceSAndroid Build Coastguard Worker     void addUniform(const Uniform &uniform)
346*35238bceSAndroid Build Coastguard Worker     {
347*35238bceSAndroid Build Coastguard Worker         m_uniforms.push_back(uniform);
348*35238bceSAndroid Build Coastguard Worker     }
addStructType(const StructType * const type)349*35238bceSAndroid Build Coastguard Worker     void addStructType(const StructType *const type)
350*35238bceSAndroid Build Coastguard Worker     {
351*35238bceSAndroid Build Coastguard Worker         m_structTypes.push_back(type);
352*35238bceSAndroid Build Coastguard Worker     }
353*35238bceSAndroid Build Coastguard Worker 
UniformCollection(void)354*35238bceSAndroid Build Coastguard Worker     UniformCollection(void)
355*35238bceSAndroid Build Coastguard Worker     {
356*35238bceSAndroid Build Coastguard Worker     }
~UniformCollection(void)357*35238bceSAndroid Build Coastguard Worker     ~UniformCollection(void)
358*35238bceSAndroid Build Coastguard Worker     {
359*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < (int)m_structTypes.size(); i++)
360*35238bceSAndroid Build Coastguard Worker             delete m_structTypes[i];
361*35238bceSAndroid Build Coastguard Worker     }
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker     // Add the contents of m_uniforms and m_structTypes to receiver, and remove them from this one.
364*35238bceSAndroid Build Coastguard Worker     // \note receiver takes ownership of the struct types.
moveContents(UniformCollection & receiver)365*35238bceSAndroid Build Coastguard Worker     void moveContents(UniformCollection &receiver)
366*35238bceSAndroid Build Coastguard Worker     {
367*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < (int)m_uniforms.size(); i++)
368*35238bceSAndroid Build Coastguard Worker             receiver.addUniform(m_uniforms[i]);
369*35238bceSAndroid Build Coastguard Worker         m_uniforms.clear();
370*35238bceSAndroid Build Coastguard Worker 
371*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < (int)m_structTypes.size(); i++)
372*35238bceSAndroid Build Coastguard Worker             receiver.addStructType(m_structTypes[i]);
373*35238bceSAndroid Build Coastguard Worker         m_structTypes.clear();
374*35238bceSAndroid Build Coastguard Worker     }
375*35238bceSAndroid Build Coastguard Worker 
containsMatchingBasicType(const dataTypePredicate predicate) const376*35238bceSAndroid Build Coastguard Worker     bool containsMatchingBasicType(const dataTypePredicate predicate) const
377*35238bceSAndroid Build Coastguard Worker     {
378*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < (int)m_uniforms.size(); i++)
379*35238bceSAndroid Build Coastguard Worker             if (typeContainsMatchingBasicType(m_uniforms[i].type, predicate))
380*35238bceSAndroid Build Coastguard Worker                 return true;
381*35238bceSAndroid Build Coastguard Worker         return false;
382*35238bceSAndroid Build Coastguard Worker     }
383*35238bceSAndroid Build Coastguard Worker 
getSamplerTypes(void) const384*35238bceSAndroid Build Coastguard Worker     vector<glu::DataType> getSamplerTypes(void) const
385*35238bceSAndroid Build Coastguard Worker     {
386*35238bceSAndroid Build Coastguard Worker         vector<glu::DataType> samplerTypes;
387*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < (int)m_uniforms.size(); i++)
388*35238bceSAndroid Build Coastguard Worker             getDistinctSamplerTypes(samplerTypes, m_uniforms[i].type);
389*35238bceSAndroid Build Coastguard Worker         return samplerTypes;
390*35238bceSAndroid Build Coastguard Worker     }
391*35238bceSAndroid Build Coastguard Worker 
containsSeveralSamplerTypes(void) const392*35238bceSAndroid Build Coastguard Worker     bool containsSeveralSamplerTypes(void) const
393*35238bceSAndroid Build Coastguard Worker     {
394*35238bceSAndroid Build Coastguard Worker         return getSamplerTypes().size() > 1;
395*35238bceSAndroid Build Coastguard Worker     }
396*35238bceSAndroid Build Coastguard Worker 
getNumSamplers(void) const397*35238bceSAndroid Build Coastguard Worker     int getNumSamplers(void) const
398*35238bceSAndroid Build Coastguard Worker     {
399*35238bceSAndroid Build Coastguard Worker         int sum = 0;
400*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < (int)m_uniforms.size(); i++)
401*35238bceSAndroid Build Coastguard Worker             sum += getNumSamplersInType(m_uniforms[i].type);
402*35238bceSAndroid Build Coastguard Worker         return sum;
403*35238bceSAndroid Build Coastguard Worker     }
404*35238bceSAndroid Build Coastguard Worker 
basic(const glu::DataType type,const char * const nameSuffix="")405*35238bceSAndroid Build Coastguard Worker     static UniformCollection *basic(const glu::DataType type, const char *const nameSuffix = "")
406*35238bceSAndroid Build Coastguard Worker     {
407*35238bceSAndroid Build Coastguard Worker         UniformCollection *const res = new UniformCollection;
408*35238bceSAndroid Build Coastguard Worker         const glu::Precision prec    = glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
409*35238bceSAndroid Build Coastguard Worker         res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(type, prec)));
410*35238bceSAndroid Build Coastguard Worker         return res;
411*35238bceSAndroid Build Coastguard Worker     }
412*35238bceSAndroid Build Coastguard Worker 
basicArray(const glu::DataType type,const char * const nameSuffix="")413*35238bceSAndroid Build Coastguard Worker     static UniformCollection *basicArray(const glu::DataType type, const char *const nameSuffix = "")
414*35238bceSAndroid Build Coastguard Worker     {
415*35238bceSAndroid Build Coastguard Worker         UniformCollection *const res = new UniformCollection;
416*35238bceSAndroid Build Coastguard Worker         const glu::Precision prec    = glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
417*35238bceSAndroid Build Coastguard Worker         res->m_uniforms.push_back(
418*35238bceSAndroid Build Coastguard Worker             Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(glu::VarType(type, prec), 3)));
419*35238bceSAndroid Build Coastguard Worker         return res;
420*35238bceSAndroid Build Coastguard Worker     }
421*35238bceSAndroid Build Coastguard Worker 
basicStruct(const glu::DataType type0,const glu::DataType type1,const bool containsArrays,const char * const nameSuffix="")422*35238bceSAndroid Build Coastguard Worker     static UniformCollection *basicStruct(const glu::DataType type0, const glu::DataType type1,
423*35238bceSAndroid Build Coastguard Worker                                           const bool containsArrays, const char *const nameSuffix = "")
424*35238bceSAndroid Build Coastguard Worker     {
425*35238bceSAndroid Build Coastguard Worker         UniformCollection *const res = new UniformCollection;
426*35238bceSAndroid Build Coastguard Worker         const glu::Precision prec0   = glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
427*35238bceSAndroid Build Coastguard Worker         const glu::Precision prec1   = glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
428*35238bceSAndroid Build Coastguard Worker 
429*35238bceSAndroid Build Coastguard Worker         StructType *const structType = new StructType((string("structType") + nameSuffix).c_str());
430*35238bceSAndroid Build Coastguard Worker         structType->addMember("m0", glu::VarType(type0, prec0));
431*35238bceSAndroid Build Coastguard Worker         structType->addMember("m1", glu::VarType(type1, prec1));
432*35238bceSAndroid Build Coastguard Worker         if (containsArrays)
433*35238bceSAndroid Build Coastguard Worker         {
434*35238bceSAndroid Build Coastguard Worker             structType->addMember("m2", glu::VarType(glu::VarType(type0, prec0), 3));
435*35238bceSAndroid Build Coastguard Worker             structType->addMember("m3", glu::VarType(glu::VarType(type1, prec1), 3));
436*35238bceSAndroid Build Coastguard Worker         }
437*35238bceSAndroid Build Coastguard Worker 
438*35238bceSAndroid Build Coastguard Worker         res->addStructType(structType);
439*35238bceSAndroid Build Coastguard Worker         res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType)));
440*35238bceSAndroid Build Coastguard Worker 
441*35238bceSAndroid Build Coastguard Worker         return res;
442*35238bceSAndroid Build Coastguard Worker     }
443*35238bceSAndroid Build Coastguard Worker 
structInArray(const glu::DataType type0,const glu::DataType type1,const bool containsArrays,const char * const nameSuffix="")444*35238bceSAndroid Build Coastguard Worker     static UniformCollection *structInArray(const glu::DataType type0, const glu::DataType type1,
445*35238bceSAndroid Build Coastguard Worker                                             const bool containsArrays, const char *const nameSuffix = "")
446*35238bceSAndroid Build Coastguard Worker     {
447*35238bceSAndroid Build Coastguard Worker         UniformCollection *const res = basicStruct(type0, type1, containsArrays, nameSuffix);
448*35238bceSAndroid Build Coastguard Worker         res->getUniform(0).type      = glu::VarType(res->getUniform(0).type, 3);
449*35238bceSAndroid Build Coastguard Worker         return res;
450*35238bceSAndroid Build Coastguard Worker     }
451*35238bceSAndroid Build Coastguard Worker 
nestedArraysStructs(const glu::DataType type0,const glu::DataType type1,const char * const nameSuffix="")452*35238bceSAndroid Build Coastguard Worker     static UniformCollection *nestedArraysStructs(const glu::DataType type0, const glu::DataType type1,
453*35238bceSAndroid Build Coastguard Worker                                                   const char *const nameSuffix = "")
454*35238bceSAndroid Build Coastguard Worker     {
455*35238bceSAndroid Build Coastguard Worker         UniformCollection *const res = new UniformCollection;
456*35238bceSAndroid Build Coastguard Worker         const glu::Precision prec0   = glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
457*35238bceSAndroid Build Coastguard Worker         const glu::Precision prec1   = glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
458*35238bceSAndroid Build Coastguard Worker         StructType *const structType = new StructType((string("structType") + nameSuffix).c_str());
459*35238bceSAndroid Build Coastguard Worker         StructType *const subStructType    = new StructType((string("subStructType") + nameSuffix).c_str());
460*35238bceSAndroid Build Coastguard Worker         StructType *const subSubStructType = new StructType((string("subSubStructType") + nameSuffix).c_str());
461*35238bceSAndroid Build Coastguard Worker 
462*35238bceSAndroid Build Coastguard Worker         subSubStructType->addMember("mss0", glu::VarType(type0, prec0));
463*35238bceSAndroid Build Coastguard Worker         subSubStructType->addMember("mss1", glu::VarType(type1, prec1));
464*35238bceSAndroid Build Coastguard Worker 
465*35238bceSAndroid Build Coastguard Worker         subStructType->addMember("ms0", glu::VarType(type1, prec1));
466*35238bceSAndroid Build Coastguard Worker         subStructType->addMember("ms1", glu::VarType(glu::VarType(type0, prec0), 2));
467*35238bceSAndroid Build Coastguard Worker         subStructType->addMember("ms2", glu::VarType(glu::VarType(subSubStructType), 2));
468*35238bceSAndroid Build Coastguard Worker 
469*35238bceSAndroid Build Coastguard Worker         structType->addMember("m0", glu::VarType(type0, prec0));
470*35238bceSAndroid Build Coastguard Worker         structType->addMember("m1", glu::VarType(subStructType));
471*35238bceSAndroid Build Coastguard Worker         structType->addMember("m2", glu::VarType(type1, prec1));
472*35238bceSAndroid Build Coastguard Worker 
473*35238bceSAndroid Build Coastguard Worker         res->addStructType(subSubStructType);
474*35238bceSAndroid Build Coastguard Worker         res->addStructType(subStructType);
475*35238bceSAndroid Build Coastguard Worker         res->addStructType(structType);
476*35238bceSAndroid Build Coastguard Worker 
477*35238bceSAndroid Build Coastguard Worker         res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType)));
478*35238bceSAndroid Build Coastguard Worker 
479*35238bceSAndroid Build Coastguard Worker         return res;
480*35238bceSAndroid Build Coastguard Worker     }
481*35238bceSAndroid Build Coastguard Worker 
multipleBasic(const char * const nameSuffix="")482*35238bceSAndroid Build Coastguard Worker     static UniformCollection *multipleBasic(const char *const nameSuffix = "")
483*35238bceSAndroid Build Coastguard Worker     {
484*35238bceSAndroid Build Coastguard Worker         static const glu::DataType types[] = {glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_UINT_VEC4,
485*35238bceSAndroid Build Coastguard Worker                                               glu::TYPE_FLOAT_MAT3, glu::TYPE_BOOL_VEC2};
486*35238bceSAndroid Build Coastguard Worker         UniformCollection *const res       = new UniformCollection;
487*35238bceSAndroid Build Coastguard Worker 
488*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++)
489*35238bceSAndroid Build Coastguard Worker         {
490*35238bceSAndroid Build Coastguard Worker             UniformCollection *const sub = basic(types[i], ("_" + de::toString(i) + nameSuffix).c_str());
491*35238bceSAndroid Build Coastguard Worker             sub->moveContents(*res);
492*35238bceSAndroid Build Coastguard Worker             delete sub;
493*35238bceSAndroid Build Coastguard Worker         }
494*35238bceSAndroid Build Coastguard Worker 
495*35238bceSAndroid Build Coastguard Worker         return res;
496*35238bceSAndroid Build Coastguard Worker     }
497*35238bceSAndroid Build Coastguard Worker 
multipleBasicArray(const char * const nameSuffix="")498*35238bceSAndroid Build Coastguard Worker     static UniformCollection *multipleBasicArray(const char *const nameSuffix = "")
499*35238bceSAndroid Build Coastguard Worker     {
500*35238bceSAndroid Build Coastguard Worker         static const glu::DataType types[] = {glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_BOOL_VEC2};
501*35238bceSAndroid Build Coastguard Worker         UniformCollection *const res       = new UniformCollection;
502*35238bceSAndroid Build Coastguard Worker 
503*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++)
504*35238bceSAndroid Build Coastguard Worker         {
505*35238bceSAndroid Build Coastguard Worker             UniformCollection *const sub = basicArray(types[i], ("_" + de::toString(i) + nameSuffix).c_str());
506*35238bceSAndroid Build Coastguard Worker             sub->moveContents(*res);
507*35238bceSAndroid Build Coastguard Worker             delete sub;
508*35238bceSAndroid Build Coastguard Worker         }
509*35238bceSAndroid Build Coastguard Worker 
510*35238bceSAndroid Build Coastguard Worker         return res;
511*35238bceSAndroid Build Coastguard Worker     }
512*35238bceSAndroid Build Coastguard Worker 
multipleNestedArraysStructs(const char * const nameSuffix="")513*35238bceSAndroid Build Coastguard Worker     static UniformCollection *multipleNestedArraysStructs(const char *const nameSuffix = "")
514*35238bceSAndroid Build Coastguard Worker     {
515*35238bceSAndroid Build Coastguard Worker         static const glu::DataType types0[] = {glu::TYPE_FLOAT, glu::TYPE_INT, glu::TYPE_BOOL_VEC4};
516*35238bceSAndroid Build Coastguard Worker         static const glu::DataType types1[] = {glu::TYPE_FLOAT_VEC4, glu::TYPE_INT_VEC4, glu::TYPE_BOOL};
517*35238bceSAndroid Build Coastguard Worker         UniformCollection *const res        = new UniformCollection;
518*35238bceSAndroid Build Coastguard Worker 
519*35238bceSAndroid Build Coastguard Worker         DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types0) == DE_LENGTH_OF_ARRAY(types1));
520*35238bceSAndroid Build Coastguard Worker 
521*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < DE_LENGTH_OF_ARRAY(types0); i++)
522*35238bceSAndroid Build Coastguard Worker         {
523*35238bceSAndroid Build Coastguard Worker             UniformCollection *const sub =
524*35238bceSAndroid Build Coastguard Worker                 nestedArraysStructs(types0[i], types1[i], ("_" + de::toString(i) + nameSuffix).c_str());
525*35238bceSAndroid Build Coastguard Worker             sub->moveContents(*res);
526*35238bceSAndroid Build Coastguard Worker             delete sub;
527*35238bceSAndroid Build Coastguard Worker         }
528*35238bceSAndroid Build Coastguard Worker 
529*35238bceSAndroid Build Coastguard Worker         return res;
530*35238bceSAndroid Build Coastguard Worker     }
531*35238bceSAndroid Build Coastguard Worker 
random(const uint32_t seed)532*35238bceSAndroid Build Coastguard Worker     static UniformCollection *random(const uint32_t seed)
533*35238bceSAndroid Build Coastguard Worker     {
534*35238bceSAndroid Build Coastguard Worker         Random rnd(seed);
535*35238bceSAndroid Build Coastguard Worker         const int numUniforms        = rnd.getInt(1, 5);
536*35238bceSAndroid Build Coastguard Worker         int structIdx                = 0;
537*35238bceSAndroid Build Coastguard Worker         UniformCollection *const res = new UniformCollection;
538*35238bceSAndroid Build Coastguard Worker 
539*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numUniforms; i++)
540*35238bceSAndroid Build Coastguard Worker         {
541*35238bceSAndroid Build Coastguard Worker             vector<const StructType *> structTypes;
542*35238bceSAndroid Build Coastguard Worker             Uniform uniform(("u_var" + de::toString(i)).c_str(), glu::VarType());
543*35238bceSAndroid Build Coastguard Worker 
544*35238bceSAndroid Build Coastguard Worker             // \note Discard uniforms that would cause number of samplers to exceed MAX_NUM_SAMPLER_UNIFORMS.
545*35238bceSAndroid Build Coastguard Worker             do
546*35238bceSAndroid Build Coastguard Worker             {
547*35238bceSAndroid Build Coastguard Worker                 for (int j = 0; j < (int)structTypes.size(); j++)
548*35238bceSAndroid Build Coastguard Worker                     delete structTypes[j];
549*35238bceSAndroid Build Coastguard Worker                 structTypes.clear();
550*35238bceSAndroid Build Coastguard Worker                 uniform.type = generateRandomType(3, structIdx, structTypes, rnd);
551*35238bceSAndroid Build Coastguard Worker             } while (res->getNumSamplers() + getNumSamplersInType(uniform.type) > MAX_NUM_SAMPLER_UNIFORMS);
552*35238bceSAndroid Build Coastguard Worker 
553*35238bceSAndroid Build Coastguard Worker             res->addUniform(uniform);
554*35238bceSAndroid Build Coastguard Worker             for (int j = 0; j < (int)structTypes.size(); j++)
555*35238bceSAndroid Build Coastguard Worker                 res->addStructType(structTypes[j]);
556*35238bceSAndroid Build Coastguard Worker         }
557*35238bceSAndroid Build Coastguard Worker 
558*35238bceSAndroid Build Coastguard Worker         return res;
559*35238bceSAndroid Build Coastguard Worker     }
560*35238bceSAndroid Build Coastguard Worker 
561*35238bceSAndroid Build Coastguard Worker private:
562*35238bceSAndroid Build Coastguard Worker     // \note Copying these would be cumbersome, since deep-copying both m_uniforms and m_structTypes
563*35238bceSAndroid Build Coastguard Worker     // would mean that we'd need to update pointers from uniforms to point to the new structTypes.
564*35238bceSAndroid Build Coastguard Worker     // When the same UniformCollection is needed in several places, a SharedPtr is used instead.
565*35238bceSAndroid Build Coastguard Worker     UniformCollection(const UniformCollection &);            // Not allowed.
566*35238bceSAndroid Build Coastguard Worker     UniformCollection &operator=(const UniformCollection &); // Not allowed.
567*35238bceSAndroid Build Coastguard Worker 
568*35238bceSAndroid Build Coastguard Worker     vector<Uniform> m_uniforms;
569*35238bceSAndroid Build Coastguard Worker     vector<const StructType *> m_structTypes;
570*35238bceSAndroid Build Coastguard Worker };
571*35238bceSAndroid Build Coastguard Worker 
572*35238bceSAndroid Build Coastguard Worker } // namespace
573*35238bceSAndroid Build Coastguard Worker 
getSamplerFillValue(const VarValue & sampler)574*35238bceSAndroid Build Coastguard Worker static VarValue getSamplerFillValue(const VarValue &sampler)
575*35238bceSAndroid Build Coastguard Worker {
576*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(glu::isDataTypeSampler(sampler.type));
577*35238bceSAndroid Build Coastguard Worker 
578*35238bceSAndroid Build Coastguard Worker     VarValue result;
579*35238bceSAndroid Build Coastguard Worker     result.type = getSamplerLookupReturnType(sampler.type);
580*35238bceSAndroid Build Coastguard Worker 
581*35238bceSAndroid Build Coastguard Worker     switch (result.type)
582*35238bceSAndroid Build Coastguard Worker     {
583*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_FLOAT_VEC4:
584*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 4; i++)
585*35238bceSAndroid Build Coastguard Worker             result.val.floatV[i] = sampler.val.samplerV.fillColor.floatV[i];
586*35238bceSAndroid Build Coastguard Worker         break;
587*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_VEC4:
588*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 4; i++)
589*35238bceSAndroid Build Coastguard Worker             result.val.uintV[i] = sampler.val.samplerV.fillColor.uintV[i];
590*35238bceSAndroid Build Coastguard Worker         break;
591*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_VEC4:
592*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 4; i++)
593*35238bceSAndroid Build Coastguard Worker             result.val.intV[i] = sampler.val.samplerV.fillColor.intV[i];
594*35238bceSAndroid Build Coastguard Worker         break;
595*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_FLOAT:
596*35238bceSAndroid Build Coastguard Worker         result.val.floatV[0] = sampler.val.samplerV.fillColor.floatV[0];
597*35238bceSAndroid Build Coastguard Worker         break;
598*35238bceSAndroid Build Coastguard Worker     default:
599*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
600*35238bceSAndroid Build Coastguard Worker     }
601*35238bceSAndroid Build Coastguard Worker 
602*35238bceSAndroid Build Coastguard Worker     return result;
603*35238bceSAndroid Build Coastguard Worker }
604*35238bceSAndroid Build Coastguard Worker 
getSamplerUnitValue(const VarValue & sampler)605*35238bceSAndroid Build Coastguard Worker static VarValue getSamplerUnitValue(const VarValue &sampler)
606*35238bceSAndroid Build Coastguard Worker {
607*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(glu::isDataTypeSampler(sampler.type));
608*35238bceSAndroid Build Coastguard Worker 
609*35238bceSAndroid Build Coastguard Worker     VarValue result;
610*35238bceSAndroid Build Coastguard Worker     result.type        = glu::TYPE_INT;
611*35238bceSAndroid Build Coastguard Worker     result.val.intV[0] = sampler.val.samplerV.unit;
612*35238bceSAndroid Build Coastguard Worker 
613*35238bceSAndroid Build Coastguard Worker     return result;
614*35238bceSAndroid Build Coastguard Worker }
615*35238bceSAndroid Build Coastguard Worker 
getDataTypeTransposedMatrix(const glu::DataType original)616*35238bceSAndroid Build Coastguard Worker static glu::DataType getDataTypeTransposedMatrix(const glu::DataType original)
617*35238bceSAndroid Build Coastguard Worker {
618*35238bceSAndroid Build Coastguard Worker     return glu::getDataTypeMatrix(glu::getDataTypeMatrixNumRows(original), glu::getDataTypeMatrixNumColumns(original));
619*35238bceSAndroid Build Coastguard Worker }
620*35238bceSAndroid Build Coastguard Worker 
getTransposeMatrix(const VarValue & original)621*35238bceSAndroid Build Coastguard Worker static VarValue getTransposeMatrix(const VarValue &original)
622*35238bceSAndroid Build Coastguard Worker {
623*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(glu::isDataTypeMatrix(original.type));
624*35238bceSAndroid Build Coastguard Worker 
625*35238bceSAndroid Build Coastguard Worker     const int rows = glu::getDataTypeMatrixNumRows(original.type);
626*35238bceSAndroid Build Coastguard Worker     const int cols = glu::getDataTypeMatrixNumColumns(original.type);
627*35238bceSAndroid Build Coastguard Worker     VarValue result;
628*35238bceSAndroid Build Coastguard Worker     result.type = getDataTypeTransposedMatrix(original.type);
629*35238bceSAndroid Build Coastguard Worker 
630*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < rows; i++)
631*35238bceSAndroid Build Coastguard Worker         for (int j = 0; j < cols; j++)
632*35238bceSAndroid Build Coastguard Worker             result.val.floatV[i * cols + j] = original.val.floatV[j * rows + i];
633*35238bceSAndroid Build Coastguard Worker 
634*35238bceSAndroid Build Coastguard Worker     return result;
635*35238bceSAndroid Build Coastguard Worker }
636*35238bceSAndroid Build Coastguard Worker 
shaderVarValueStr(const VarValue & value)637*35238bceSAndroid Build Coastguard Worker static string shaderVarValueStr(const VarValue &value)
638*35238bceSAndroid Build Coastguard Worker {
639*35238bceSAndroid Build Coastguard Worker     const int numElems = glu::getDataTypeScalarSize(value.type);
640*35238bceSAndroid Build Coastguard Worker     std::ostringstream result;
641*35238bceSAndroid Build Coastguard Worker 
642*35238bceSAndroid Build Coastguard Worker     if (numElems > 1)
643*35238bceSAndroid Build Coastguard Worker         result << glu::getDataTypeName(value.type) << "(";
644*35238bceSAndroid Build Coastguard Worker 
645*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numElems; i++)
646*35238bceSAndroid Build Coastguard Worker     {
647*35238bceSAndroid Build Coastguard Worker         if (i > 0)
648*35238bceSAndroid Build Coastguard Worker             result << ", ";
649*35238bceSAndroid Build Coastguard Worker 
650*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type))
651*35238bceSAndroid Build Coastguard Worker             result << de::floatToString(value.val.floatV[i], 2);
652*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeIntOrIVec((value.type)))
653*35238bceSAndroid Build Coastguard Worker             result << de::toString(value.val.intV[i]);
654*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeUintOrUVec((value.type)))
655*35238bceSAndroid Build Coastguard Worker             result << de::toString(value.val.uintV[i]) << "u";
656*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeBoolOrBVec((value.type)))
657*35238bceSAndroid Build Coastguard Worker             result << (value.val.boolV[i] ? "true" : "false");
658*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeSampler((value.type)))
659*35238bceSAndroid Build Coastguard Worker             result << shaderVarValueStr(getSamplerFillValue(value));
660*35238bceSAndroid Build Coastguard Worker         else
661*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
662*35238bceSAndroid Build Coastguard Worker     }
663*35238bceSAndroid Build Coastguard Worker 
664*35238bceSAndroid Build Coastguard Worker     if (numElems > 1)
665*35238bceSAndroid Build Coastguard Worker         result << ")";
666*35238bceSAndroid Build Coastguard Worker 
667*35238bceSAndroid Build Coastguard Worker     return result.str();
668*35238bceSAndroid Build Coastguard Worker }
669*35238bceSAndroid Build Coastguard Worker 
apiVarValueStr(const VarValue & value)670*35238bceSAndroid Build Coastguard Worker static string apiVarValueStr(const VarValue &value)
671*35238bceSAndroid Build Coastguard Worker {
672*35238bceSAndroid Build Coastguard Worker     const int numElems = glu::getDataTypeScalarSize(value.type);
673*35238bceSAndroid Build Coastguard Worker     std::ostringstream result;
674*35238bceSAndroid Build Coastguard Worker 
675*35238bceSAndroid Build Coastguard Worker     if (numElems > 1)
676*35238bceSAndroid Build Coastguard Worker         result << "(";
677*35238bceSAndroid Build Coastguard Worker 
678*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numElems; i++)
679*35238bceSAndroid Build Coastguard Worker     {
680*35238bceSAndroid Build Coastguard Worker         if (i > 0)
681*35238bceSAndroid Build Coastguard Worker             result << ", ";
682*35238bceSAndroid Build Coastguard Worker 
683*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type))
684*35238bceSAndroid Build Coastguard Worker             result << de::floatToString(value.val.floatV[i], 2);
685*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeIntOrIVec((value.type)))
686*35238bceSAndroid Build Coastguard Worker             result << de::toString(value.val.intV[i]);
687*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeUintOrUVec((value.type)))
688*35238bceSAndroid Build Coastguard Worker             result << de::toString(value.val.uintV[i]);
689*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeBoolOrBVec((value.type)))
690*35238bceSAndroid Build Coastguard Worker             result << (value.val.boolV[i] ? "true" : "false");
691*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeSampler((value.type)))
692*35238bceSAndroid Build Coastguard Worker             result << value.val.samplerV.unit;
693*35238bceSAndroid Build Coastguard Worker         else
694*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
695*35238bceSAndroid Build Coastguard Worker     }
696*35238bceSAndroid Build Coastguard Worker 
697*35238bceSAndroid Build Coastguard Worker     if (numElems > 1)
698*35238bceSAndroid Build Coastguard Worker         result << ")";
699*35238bceSAndroid Build Coastguard Worker 
700*35238bceSAndroid Build Coastguard Worker     return result.str();
701*35238bceSAndroid Build Coastguard Worker }
702*35238bceSAndroid Build Coastguard Worker 
generateRandomVarValue(const glu::DataType type,Random & rnd,int samplerUnit=-1)703*35238bceSAndroid Build Coastguard Worker static VarValue generateRandomVarValue(
704*35238bceSAndroid Build Coastguard Worker     const glu::DataType type, Random &rnd,
705*35238bceSAndroid Build Coastguard Worker     int samplerUnit = -1 /* Used if type is a sampler type. \note Samplers' unit numbers are not randomized. */)
706*35238bceSAndroid Build Coastguard Worker {
707*35238bceSAndroid Build Coastguard Worker     const int numElems = glu::getDataTypeScalarSize(type);
708*35238bceSAndroid Build Coastguard Worker     VarValue result;
709*35238bceSAndroid Build Coastguard Worker     result.type = type;
710*35238bceSAndroid Build Coastguard Worker 
711*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((samplerUnit >= 0) == (glu::isDataTypeSampler(type)));
712*35238bceSAndroid Build Coastguard Worker 
713*35238bceSAndroid Build Coastguard Worker     if (glu::isDataTypeFloatOrVec(type) || glu::isDataTypeMatrix(type))
714*35238bceSAndroid Build Coastguard Worker     {
715*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numElems; i++)
716*35238bceSAndroid Build Coastguard Worker             result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f);
717*35238bceSAndroid Build Coastguard Worker     }
718*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeIntOrIVec(type))
719*35238bceSAndroid Build Coastguard Worker     {
720*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numElems; i++)
721*35238bceSAndroid Build Coastguard Worker             result.val.intV[i] = rnd.getInt(-10, 10);
722*35238bceSAndroid Build Coastguard Worker     }
723*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeUintOrUVec(type))
724*35238bceSAndroid Build Coastguard Worker     {
725*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numElems; i++)
726*35238bceSAndroid Build Coastguard Worker             result.val.uintV[i] = (uint32_t)rnd.getInt(0, 10);
727*35238bceSAndroid Build Coastguard Worker     }
728*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeBoolOrBVec(type))
729*35238bceSAndroid Build Coastguard Worker     {
730*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numElems; i++)
731*35238bceSAndroid Build Coastguard Worker             result.val.boolV[i] = rnd.getBool();
732*35238bceSAndroid Build Coastguard Worker     }
733*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeSampler(type))
734*35238bceSAndroid Build Coastguard Worker     {
735*35238bceSAndroid Build Coastguard Worker         const glu::DataType texResultType       = getSamplerLookupReturnType(type);
736*35238bceSAndroid Build Coastguard Worker         const glu::DataType texResultScalarType = glu::getDataTypeScalarType(texResultType);
737*35238bceSAndroid Build Coastguard Worker         const int texResultNumDims              = glu::getDataTypeScalarSize(texResultType);
738*35238bceSAndroid Build Coastguard Worker 
739*35238bceSAndroid Build Coastguard Worker         result.val.samplerV.unit = samplerUnit;
740*35238bceSAndroid Build Coastguard Worker 
741*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < texResultNumDims; i++)
742*35238bceSAndroid Build Coastguard Worker         {
743*35238bceSAndroid Build Coastguard Worker             switch (texResultScalarType)
744*35238bceSAndroid Build Coastguard Worker             {
745*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT:
746*35238bceSAndroid Build Coastguard Worker                 result.val.samplerV.fillColor.floatV[i] = rnd.getFloat(0.0f, 1.0f);
747*35238bceSAndroid Build Coastguard Worker                 break;
748*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_INT:
749*35238bceSAndroid Build Coastguard Worker                 result.val.samplerV.fillColor.intV[i] = rnd.getInt(-10, 10);
750*35238bceSAndroid Build Coastguard Worker                 break;
751*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_UINT:
752*35238bceSAndroid Build Coastguard Worker                 result.val.samplerV.fillColor.uintV[i] = (uint32_t)rnd.getInt(0, 10);
753*35238bceSAndroid Build Coastguard Worker                 break;
754*35238bceSAndroid Build Coastguard Worker             default:
755*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
756*35238bceSAndroid Build Coastguard Worker             }
757*35238bceSAndroid Build Coastguard Worker         }
758*35238bceSAndroid Build Coastguard Worker     }
759*35238bceSAndroid Build Coastguard Worker     else
760*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
761*35238bceSAndroid Build Coastguard Worker 
762*35238bceSAndroid Build Coastguard Worker     return result;
763*35238bceSAndroid Build Coastguard Worker }
764*35238bceSAndroid Build Coastguard Worker 
generateZeroVarValue(const glu::DataType type)765*35238bceSAndroid Build Coastguard Worker static VarValue generateZeroVarValue(const glu::DataType type)
766*35238bceSAndroid Build Coastguard Worker {
767*35238bceSAndroid Build Coastguard Worker     const int numElems = glu::getDataTypeScalarSize(type);
768*35238bceSAndroid Build Coastguard Worker     VarValue result;
769*35238bceSAndroid Build Coastguard Worker     result.type = type;
770*35238bceSAndroid Build Coastguard Worker 
771*35238bceSAndroid Build Coastguard Worker     if (glu::isDataTypeFloatOrVec(type) || glu::isDataTypeMatrix(type))
772*35238bceSAndroid Build Coastguard Worker     {
773*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numElems; i++)
774*35238bceSAndroid Build Coastguard Worker             result.val.floatV[i] = 0.0f;
775*35238bceSAndroid Build Coastguard Worker     }
776*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeIntOrIVec(type))
777*35238bceSAndroid Build Coastguard Worker     {
778*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numElems; i++)
779*35238bceSAndroid Build Coastguard Worker             result.val.intV[i] = 0;
780*35238bceSAndroid Build Coastguard Worker     }
781*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeUintOrUVec(type))
782*35238bceSAndroid Build Coastguard Worker     {
783*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numElems; i++)
784*35238bceSAndroid Build Coastguard Worker             result.val.uintV[i] = 0u;
785*35238bceSAndroid Build Coastguard Worker     }
786*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeBoolOrBVec(type))
787*35238bceSAndroid Build Coastguard Worker     {
788*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numElems; i++)
789*35238bceSAndroid Build Coastguard Worker             result.val.boolV[i] = false;
790*35238bceSAndroid Build Coastguard Worker     }
791*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeSampler(type))
792*35238bceSAndroid Build Coastguard Worker     {
793*35238bceSAndroid Build Coastguard Worker         const glu::DataType texResultType       = getSamplerLookupReturnType(type);
794*35238bceSAndroid Build Coastguard Worker         const glu::DataType texResultScalarType = glu::getDataTypeScalarType(texResultType);
795*35238bceSAndroid Build Coastguard Worker         const int texResultNumDims              = glu::getDataTypeScalarSize(texResultType);
796*35238bceSAndroid Build Coastguard Worker 
797*35238bceSAndroid Build Coastguard Worker         result.val.samplerV.unit = 0;
798*35238bceSAndroid Build Coastguard Worker 
799*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < texResultNumDims; i++)
800*35238bceSAndroid Build Coastguard Worker         {
801*35238bceSAndroid Build Coastguard Worker             switch (texResultScalarType)
802*35238bceSAndroid Build Coastguard Worker             {
803*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT:
804*35238bceSAndroid Build Coastguard Worker                 result.val.samplerV.fillColor.floatV[i] = 0.12f * (float)i;
805*35238bceSAndroid Build Coastguard Worker                 break;
806*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_INT:
807*35238bceSAndroid Build Coastguard Worker                 result.val.samplerV.fillColor.intV[i] = -2 + i;
808*35238bceSAndroid Build Coastguard Worker                 break;
809*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_UINT:
810*35238bceSAndroid Build Coastguard Worker                 result.val.samplerV.fillColor.uintV[i] = 4 + i;
811*35238bceSAndroid Build Coastguard Worker                 break;
812*35238bceSAndroid Build Coastguard Worker             default:
813*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
814*35238bceSAndroid Build Coastguard Worker             }
815*35238bceSAndroid Build Coastguard Worker         }
816*35238bceSAndroid Build Coastguard Worker     }
817*35238bceSAndroid Build Coastguard Worker     else
818*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
819*35238bceSAndroid Build Coastguard Worker 
820*35238bceSAndroid Build Coastguard Worker     return result;
821*35238bceSAndroid Build Coastguard Worker }
822*35238bceSAndroid Build Coastguard Worker 
apiVarValueEquals(const VarValue & a,const VarValue & b)823*35238bceSAndroid Build Coastguard Worker static bool apiVarValueEquals(const VarValue &a, const VarValue &b)
824*35238bceSAndroid Build Coastguard Worker {
825*35238bceSAndroid Build Coastguard Worker     const int size             = glu::getDataTypeScalarSize(a.type);
826*35238bceSAndroid Build Coastguard Worker     const float floatThreshold = 0.05f;
827*35238bceSAndroid Build Coastguard Worker 
828*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(a.type == b.type);
829*35238bceSAndroid Build Coastguard Worker 
830*35238bceSAndroid Build Coastguard Worker     if (glu::isDataTypeFloatOrVec(a.type) || glu::isDataTypeMatrix(a.type))
831*35238bceSAndroid Build Coastguard Worker     {
832*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < size; i++)
833*35238bceSAndroid Build Coastguard Worker             if (de::abs(a.val.floatV[i] - b.val.floatV[i]) >= floatThreshold)
834*35238bceSAndroid Build Coastguard Worker                 return false;
835*35238bceSAndroid Build Coastguard Worker     }
836*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeIntOrIVec(a.type))
837*35238bceSAndroid Build Coastguard Worker     {
838*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < size; i++)
839*35238bceSAndroid Build Coastguard Worker             if (a.val.intV[i] != b.val.intV[i])
840*35238bceSAndroid Build Coastguard Worker                 return false;
841*35238bceSAndroid Build Coastguard Worker     }
842*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeUintOrUVec(a.type))
843*35238bceSAndroid Build Coastguard Worker     {
844*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < size; i++)
845*35238bceSAndroid Build Coastguard Worker             if (a.val.uintV[i] != b.val.uintV[i])
846*35238bceSAndroid Build Coastguard Worker                 return false;
847*35238bceSAndroid Build Coastguard Worker     }
848*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeBoolOrBVec(a.type))
849*35238bceSAndroid Build Coastguard Worker     {
850*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < size; i++)
851*35238bceSAndroid Build Coastguard Worker             if (a.val.boolV[i] != b.val.boolV[i])
852*35238bceSAndroid Build Coastguard Worker                 return false;
853*35238bceSAndroid Build Coastguard Worker     }
854*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeSampler(a.type))
855*35238bceSAndroid Build Coastguard Worker     {
856*35238bceSAndroid Build Coastguard Worker         if (a.val.samplerV.unit != b.val.samplerV.unit)
857*35238bceSAndroid Build Coastguard Worker             return false;
858*35238bceSAndroid Build Coastguard Worker     }
859*35238bceSAndroid Build Coastguard Worker     else
860*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
861*35238bceSAndroid Build Coastguard Worker 
862*35238bceSAndroid Build Coastguard Worker     return true;
863*35238bceSAndroid Build Coastguard Worker }
864*35238bceSAndroid Build Coastguard Worker 
getRandomBoolRepresentation(const VarValue & boolValue,const glu::DataType targetScalarType,Random & rnd)865*35238bceSAndroid Build Coastguard Worker static VarValue getRandomBoolRepresentation(const VarValue &boolValue, const glu::DataType targetScalarType,
866*35238bceSAndroid Build Coastguard Worker                                             Random &rnd)
867*35238bceSAndroid Build Coastguard Worker {
868*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(glu::isDataTypeBoolOrBVec(boolValue.type));
869*35238bceSAndroid Build Coastguard Worker 
870*35238bceSAndroid Build Coastguard Worker     const int size                 = glu::getDataTypeScalarSize(boolValue.type);
871*35238bceSAndroid Build Coastguard Worker     const glu::DataType targetType = size == 1 ? targetScalarType : glu::getDataTypeVector(targetScalarType, size);
872*35238bceSAndroid Build Coastguard Worker     VarValue result;
873*35238bceSAndroid Build Coastguard Worker     result.type = targetType;
874*35238bceSAndroid Build Coastguard Worker 
875*35238bceSAndroid Build Coastguard Worker     switch (targetScalarType)
876*35238bceSAndroid Build Coastguard Worker     {
877*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT:
878*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < size; i++)
879*35238bceSAndroid Build Coastguard Worker         {
880*35238bceSAndroid Build Coastguard Worker             if (boolValue.val.boolV[i])
881*35238bceSAndroid Build Coastguard Worker             {
882*35238bceSAndroid Build Coastguard Worker                 result.val.intV[i] = rnd.getInt(-10, 10);
883*35238bceSAndroid Build Coastguard Worker                 if (result.val.intV[i] == 0)
884*35238bceSAndroid Build Coastguard Worker                     result.val.intV[i] = 1;
885*35238bceSAndroid Build Coastguard Worker             }
886*35238bceSAndroid Build Coastguard Worker             else
887*35238bceSAndroid Build Coastguard Worker                 result.val.intV[i] = 0;
888*35238bceSAndroid Build Coastguard Worker         }
889*35238bceSAndroid Build Coastguard Worker         break;
890*35238bceSAndroid Build Coastguard Worker 
891*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT:
892*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < size; i++)
893*35238bceSAndroid Build Coastguard Worker         {
894*35238bceSAndroid Build Coastguard Worker             if (boolValue.val.boolV[i])
895*35238bceSAndroid Build Coastguard Worker                 result.val.uintV[i] = rnd.getInt(1, 10);
896*35238bceSAndroid Build Coastguard Worker             else
897*35238bceSAndroid Build Coastguard Worker                 result.val.uintV[i] = 0;
898*35238bceSAndroid Build Coastguard Worker         }
899*35238bceSAndroid Build Coastguard Worker         break;
900*35238bceSAndroid Build Coastguard Worker 
901*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_FLOAT:
902*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < size; i++)
903*35238bceSAndroid Build Coastguard Worker         {
904*35238bceSAndroid Build Coastguard Worker             if (boolValue.val.boolV[i])
905*35238bceSAndroid Build Coastguard Worker             {
906*35238bceSAndroid Build Coastguard Worker                 result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f);
907*35238bceSAndroid Build Coastguard Worker                 if (result.val.floatV[i] == 0.0f)
908*35238bceSAndroid Build Coastguard Worker                     result.val.floatV[i] = 1.0f;
909*35238bceSAndroid Build Coastguard Worker             }
910*35238bceSAndroid Build Coastguard Worker             else
911*35238bceSAndroid Build Coastguard Worker                 result.val.floatV[i] = 0;
912*35238bceSAndroid Build Coastguard Worker         }
913*35238bceSAndroid Build Coastguard Worker         break;
914*35238bceSAndroid Build Coastguard Worker 
915*35238bceSAndroid Build Coastguard Worker     default:
916*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
917*35238bceSAndroid Build Coastguard Worker     }
918*35238bceSAndroid Build Coastguard Worker 
919*35238bceSAndroid Build Coastguard Worker     return result;
920*35238bceSAndroid Build Coastguard Worker }
921*35238bceSAndroid Build Coastguard Worker 
getCaseShaderTypeName(const CaseShaderType type)922*35238bceSAndroid Build Coastguard Worker static const char *getCaseShaderTypeName(const CaseShaderType type)
923*35238bceSAndroid Build Coastguard Worker {
924*35238bceSAndroid Build Coastguard Worker     switch (type)
925*35238bceSAndroid Build Coastguard Worker     {
926*35238bceSAndroid Build Coastguard Worker     case CASESHADERTYPE_VERTEX:
927*35238bceSAndroid Build Coastguard Worker         return "vertex";
928*35238bceSAndroid Build Coastguard Worker     case CASESHADERTYPE_FRAGMENT:
929*35238bceSAndroid Build Coastguard Worker         return "fragment";
930*35238bceSAndroid Build Coastguard Worker     case CASESHADERTYPE_BOTH:
931*35238bceSAndroid Build Coastguard Worker         return "both";
932*35238bceSAndroid Build Coastguard Worker     default:
933*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
934*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
935*35238bceSAndroid Build Coastguard Worker     }
936*35238bceSAndroid Build Coastguard Worker }
937*35238bceSAndroid Build Coastguard Worker 
randomCaseShaderType(const uint32_t seed)938*35238bceSAndroid Build Coastguard Worker static CaseShaderType randomCaseShaderType(const uint32_t seed)
939*35238bceSAndroid Build Coastguard Worker {
940*35238bceSAndroid Build Coastguard Worker     return (CaseShaderType)Random(seed).getInt(0, CASESHADERTYPE_LAST - 1);
941*35238bceSAndroid Build Coastguard Worker }
942*35238bceSAndroid Build Coastguard Worker 
943*35238bceSAndroid Build Coastguard Worker class UniformCase : public TestCase, protected glu::CallLogWrapper
944*35238bceSAndroid Build Coastguard Worker {
945*35238bceSAndroid Build Coastguard Worker public:
946*35238bceSAndroid Build Coastguard Worker     enum Feature
947*35238bceSAndroid Build Coastguard Worker     {
948*35238bceSAndroid Build Coastguard Worker         // ARRAYUSAGE_ONLY_MIDDLE_INDEX: only middle index of each array is used in shader. If not given, use all indices.
949*35238bceSAndroid Build Coastguard Worker         FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX = 1 << 0,
950*35238bceSAndroid Build Coastguard Worker 
951*35238bceSAndroid Build Coastguard Worker         // UNIFORMFUNC_VALUE: use pass-by-value versions of uniform assignment funcs, e.g. glUniform1f(), where possible. If not given, use pass-by-pointer versions.
952*35238bceSAndroid Build Coastguard Worker         FEATURE_UNIFORMFUNC_VALUE = 1 << 1,
953*35238bceSAndroid Build Coastguard Worker 
954*35238bceSAndroid Build Coastguard Worker         // MATRIXMODE_ROWMAJOR: pass matrices to GL in row major form. If not given, use column major.
955*35238bceSAndroid Build Coastguard Worker         FEATURE_MATRIXMODE_ROWMAJOR = 1 << 2,
956*35238bceSAndroid Build Coastguard Worker 
957*35238bceSAndroid Build Coastguard Worker         // ARRAYASSIGN: how basic-type arrays are assigned with glUniform*(). If none given, assign each element of an array separately.
958*35238bceSAndroid Build Coastguard Worker         FEATURE_ARRAYASSIGN_FULL          = 1 << 3, //!< Assign all elements of an array with one glUniform*().
959*35238bceSAndroid Build Coastguard Worker         FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO = 1 << 4, //!< Assign two elements per one glUniform*().
960*35238bceSAndroid Build Coastguard Worker 
961*35238bceSAndroid Build Coastguard Worker         // UNIFORMUSAGE_EVERY_OTHER: use about half of the uniforms. If not given, use all uniforms (except that some array indices may be omitted according to ARRAYUSAGE).
962*35238bceSAndroid Build Coastguard Worker         FEATURE_UNIFORMUSAGE_EVERY_OTHER = 1 << 5,
963*35238bceSAndroid Build Coastguard Worker 
964*35238bceSAndroid Build Coastguard Worker         // BOOLEANAPITYPE: type used to pass booleans to and from GL api. If none given, use float.
965*35238bceSAndroid Build Coastguard Worker         FEATURE_BOOLEANAPITYPE_INT  = 1 << 6,
966*35238bceSAndroid Build Coastguard Worker         FEATURE_BOOLEANAPITYPE_UINT = 1 << 7,
967*35238bceSAndroid Build Coastguard Worker 
968*35238bceSAndroid Build Coastguard Worker         // UNIFORMVALUE_ZERO: use zero-valued uniforms. If not given, use random uniform values.
969*35238bceSAndroid Build Coastguard Worker         FEATURE_UNIFORMVALUE_ZERO = 1 << 8,
970*35238bceSAndroid Build Coastguard Worker 
971*35238bceSAndroid Build Coastguard Worker         // ARRAY_FIRST_ELEM_NAME_NO_INDEX: in certain API functions, when referring to the first element of an array, use just the array name without [0] at the end.
972*35238bceSAndroid Build Coastguard Worker         FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX = 1 << 9
973*35238bceSAndroid Build Coastguard Worker     };
974*35238bceSAndroid Build Coastguard Worker 
975*35238bceSAndroid Build Coastguard Worker     UniformCase(Context &context, const char *name, const char *description, CaseShaderType caseType,
976*35238bceSAndroid Build Coastguard Worker                 const SharedPtr<const UniformCollection> &uniformCollection, uint32_t features);
977*35238bceSAndroid Build Coastguard Worker     UniformCase(Context &context, const char *name, const char *description,
978*35238bceSAndroid Build Coastguard Worker                 uint32_t seed); // \note Randomizes caseType, uniformCollection and features.
979*35238bceSAndroid Build Coastguard Worker     virtual ~UniformCase(void);
980*35238bceSAndroid Build Coastguard Worker 
981*35238bceSAndroid Build Coastguard Worker     virtual void init(void);
982*35238bceSAndroid Build Coastguard Worker     virtual void deinit(void);
983*35238bceSAndroid Build Coastguard Worker 
984*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
985*35238bceSAndroid Build Coastguard Worker 
986*35238bceSAndroid Build Coastguard Worker protected:
987*35238bceSAndroid Build Coastguard Worker     // A basic uniform is a uniform (possibly struct or array member) whose type is a basic type (e.g. float, ivec4, sampler2d).
988*35238bceSAndroid Build Coastguard Worker     struct BasicUniform
989*35238bceSAndroid Build Coastguard Worker     {
990*35238bceSAndroid Build Coastguard Worker         string name;
991*35238bceSAndroid Build Coastguard Worker         glu::DataType type;
992*35238bceSAndroid Build Coastguard Worker         bool isUsedInShader;
993*35238bceSAndroid Build Coastguard Worker         VarValue finalValue; //!< The value we ultimately want to set for this uniform.
994*35238bceSAndroid Build Coastguard Worker 
995*35238bceSAndroid Build Coastguard Worker         string
996*35238bceSAndroid Build Coastguard Worker             rootName; //!< If this is a member of a basic-typed array, rootName is the name of that array with "[0]" appended. Otherwise it equals name.
997*35238bceSAndroid Build Coastguard Worker         int elemNdx;  //!< If this is a member of a basic-typed array, elemNdx is the index in that array. Otherwise -1.
998*35238bceSAndroid Build Coastguard Worker         int rootSize; //!< If this is a member of a basic-typed array, rootSize is the size of that array. Otherwise 1.
999*35238bceSAndroid Build Coastguard Worker 
BasicUniformdeqp::gles3::Functional::UniformCase::BasicUniform1000*35238bceSAndroid Build Coastguard Worker         BasicUniform(const char *const name_, const glu::DataType type_, const bool isUsedInShader_,
1001*35238bceSAndroid Build Coastguard Worker                      const VarValue &finalValue_, const char *const rootName_ = DE_NULL, const int elemNdx_ = -1,
1002*35238bceSAndroid Build Coastguard Worker                      const int rootSize_ = 1)
1003*35238bceSAndroid Build Coastguard Worker             : name(name_)
1004*35238bceSAndroid Build Coastguard Worker             , type(type_)
1005*35238bceSAndroid Build Coastguard Worker             , isUsedInShader(isUsedInShader_)
1006*35238bceSAndroid Build Coastguard Worker             , finalValue(finalValue_)
1007*35238bceSAndroid Build Coastguard Worker             , rootName(rootName_ == DE_NULL ? name_ : rootName_)
1008*35238bceSAndroid Build Coastguard Worker             , elemNdx(elemNdx_)
1009*35238bceSAndroid Build Coastguard Worker             , rootSize(rootSize_)
1010*35238bceSAndroid Build Coastguard Worker         {
1011*35238bceSAndroid Build Coastguard Worker         }
1012*35238bceSAndroid Build Coastguard Worker 
findWithNamedeqp::gles3::Functional::UniformCase::BasicUniform1013*35238bceSAndroid Build Coastguard Worker         static vector<BasicUniform>::const_iterator findWithName(const vector<BasicUniform> &vec,
1014*35238bceSAndroid Build Coastguard Worker                                                                  const char *const name)
1015*35238bceSAndroid Build Coastguard Worker         {
1016*35238bceSAndroid Build Coastguard Worker             for (vector<BasicUniform>::const_iterator it = vec.begin(); it != vec.end(); it++)
1017*35238bceSAndroid Build Coastguard Worker             {
1018*35238bceSAndroid Build Coastguard Worker                 if (it->name == name)
1019*35238bceSAndroid Build Coastguard Worker                     return it;
1020*35238bceSAndroid Build Coastguard Worker             }
1021*35238bceSAndroid Build Coastguard Worker             return vec.end();
1022*35238bceSAndroid Build Coastguard Worker         }
1023*35238bceSAndroid Build Coastguard Worker     };
1024*35238bceSAndroid Build Coastguard Worker 
1025*35238bceSAndroid Build Coastguard Worker     // Reference values for info that is expected to be reported by glGetActiveUniform() or glGetActiveUniformsiv().
1026*35238bceSAndroid Build Coastguard Worker     struct BasicUniformReportRef
1027*35238bceSAndroid Build Coastguard Worker     {
1028*35238bceSAndroid Build Coastguard Worker         string name;
1029*35238bceSAndroid Build Coastguard Worker         // \note minSize and maxSize are for arrays and can be distinct since implementations are allowed, but not required, to trim the inactive end indices of arrays.
1030*35238bceSAndroid Build Coastguard Worker         int minSize;
1031*35238bceSAndroid Build Coastguard Worker         int maxSize;
1032*35238bceSAndroid Build Coastguard Worker         glu::DataType type;
1033*35238bceSAndroid Build Coastguard Worker         bool isUsedInShader;
1034*35238bceSAndroid Build Coastguard Worker 
BasicUniformReportRefdeqp::gles3::Functional::UniformCase::BasicUniformReportRef1035*35238bceSAndroid Build Coastguard Worker         BasicUniformReportRef(const char *const name_, const int minS, const int maxS, const glu::DataType type_,
1036*35238bceSAndroid Build Coastguard Worker                               const bool used)
1037*35238bceSAndroid Build Coastguard Worker             : name(name_)
1038*35238bceSAndroid Build Coastguard Worker             , minSize(minS)
1039*35238bceSAndroid Build Coastguard Worker             , maxSize(maxS)
1040*35238bceSAndroid Build Coastguard Worker             , type(type_)
1041*35238bceSAndroid Build Coastguard Worker             , isUsedInShader(used)
1042*35238bceSAndroid Build Coastguard Worker         {
1043*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(minSize <= maxSize);
1044*35238bceSAndroid Build Coastguard Worker         }
BasicUniformReportRefdeqp::gles3::Functional::UniformCase::BasicUniformReportRef1045*35238bceSAndroid Build Coastguard Worker         BasicUniformReportRef(const char *const name_, const glu::DataType type_, const bool used)
1046*35238bceSAndroid Build Coastguard Worker             : name(name_)
1047*35238bceSAndroid Build Coastguard Worker             , minSize(1)
1048*35238bceSAndroid Build Coastguard Worker             , maxSize(1)
1049*35238bceSAndroid Build Coastguard Worker             , type(type_)
1050*35238bceSAndroid Build Coastguard Worker             , isUsedInShader(used)
1051*35238bceSAndroid Build Coastguard Worker         {
1052*35238bceSAndroid Build Coastguard Worker         }
1053*35238bceSAndroid Build Coastguard Worker     };
1054*35238bceSAndroid Build Coastguard Worker 
1055*35238bceSAndroid Build Coastguard Worker     // Info that is actually reported by glGetActiveUniform() or glGetActiveUniformsiv().
1056*35238bceSAndroid Build Coastguard Worker     struct BasicUniformReportGL
1057*35238bceSAndroid Build Coastguard Worker     {
1058*35238bceSAndroid Build Coastguard Worker         string name;
1059*35238bceSAndroid Build Coastguard Worker         int nameLength; // \note Whether this includes the null byte depends on whether it was queried with glGetActiveUniform() or glGetActiveUniformsiv().
1060*35238bceSAndroid Build Coastguard Worker         int size;
1061*35238bceSAndroid Build Coastguard Worker         glu::DataType type;
1062*35238bceSAndroid Build Coastguard Worker 
1063*35238bceSAndroid Build Coastguard Worker         int index;
1064*35238bceSAndroid Build Coastguard Worker 
BasicUniformReportGLdeqp::gles3::Functional::UniformCase::BasicUniformReportGL1065*35238bceSAndroid Build Coastguard Worker         BasicUniformReportGL(const char *const name_, const int nameLength_, const int size_, const glu::DataType type_,
1066*35238bceSAndroid Build Coastguard Worker                              const int index_)
1067*35238bceSAndroid Build Coastguard Worker             : name(name_)
1068*35238bceSAndroid Build Coastguard Worker             , nameLength(nameLength_)
1069*35238bceSAndroid Build Coastguard Worker             , size(size_)
1070*35238bceSAndroid Build Coastguard Worker             , type(type_)
1071*35238bceSAndroid Build Coastguard Worker             , index(index_)
1072*35238bceSAndroid Build Coastguard Worker         {
1073*35238bceSAndroid Build Coastguard Worker         }
1074*35238bceSAndroid Build Coastguard Worker 
findWithNamedeqp::gles3::Functional::UniformCase::BasicUniformReportGL1075*35238bceSAndroid Build Coastguard Worker         static vector<BasicUniformReportGL>::const_iterator findWithName(const vector<BasicUniformReportGL> &vec,
1076*35238bceSAndroid Build Coastguard Worker                                                                          const char *const name)
1077*35238bceSAndroid Build Coastguard Worker         {
1078*35238bceSAndroid Build Coastguard Worker             for (vector<BasicUniformReportGL>::const_iterator it = vec.begin(); it != vec.end(); it++)
1079*35238bceSAndroid Build Coastguard Worker             {
1080*35238bceSAndroid Build Coastguard Worker                 if (it->name == name)
1081*35238bceSAndroid Build Coastguard Worker                     return it;
1082*35238bceSAndroid Build Coastguard Worker             }
1083*35238bceSAndroid Build Coastguard Worker             return vec.end();
1084*35238bceSAndroid Build Coastguard Worker         }
1085*35238bceSAndroid Build Coastguard Worker     };
1086*35238bceSAndroid Build Coastguard Worker 
1087*35238bceSAndroid Build Coastguard Worker     // Query info with glGetActiveUniform() and check validity.
1088*35238bceSAndroid Build Coastguard Worker     bool getActiveUniforms(vector<BasicUniformReportGL> &dst, const vector<BasicUniformReportRef> &ref,
1089*35238bceSAndroid Build Coastguard Worker                            uint32_t programGL);
1090*35238bceSAndroid Build Coastguard Worker     // Query info with glGetUniformIndices() + glGetActiveUniformsiv() and check validity.
1091*35238bceSAndroid Build Coastguard Worker     bool getActiveUniformsiv(vector<BasicUniformReportGL> &dst, const vector<BasicUniformReportRef> &ref,
1092*35238bceSAndroid Build Coastguard Worker                              uint32_t programGL);
1093*35238bceSAndroid Build Coastguard Worker     // Compare infos returned by glGetActiveUniform() and glGetUniformIndices() + glGetActiveUniformsiv().
1094*35238bceSAndroid Build Coastguard Worker     bool uniformVsUniformsivComparison(const vector<BasicUniformReportGL> &uniformsResult,
1095*35238bceSAndroid Build Coastguard Worker                                        const vector<BasicUniformReportGL> &uniformsivResult);
1096*35238bceSAndroid Build Coastguard Worker     // Get uniform values with glGetUniform*() and put to valuesDst. Uniforms that get -1 from glGetUniformLocation() get glu::TYPE_INVALID.
1097*35238bceSAndroid Build Coastguard Worker     bool getUniforms(vector<VarValue> &valuesDst, const vector<BasicUniform> &basicUniforms, uint32_t programGL);
1098*35238bceSAndroid Build Coastguard Worker     // Check that every uniform has the default (zero) value.
1099*35238bceSAndroid Build Coastguard Worker     bool checkUniformDefaultValues(const vector<VarValue> &values, const vector<BasicUniform> &basicUniforms);
1100*35238bceSAndroid Build Coastguard Worker     // Assign the basicUniforms[].finalValue values for uniforms. \note rnd parameter is for booleans (true can be any nonzero value).
1101*35238bceSAndroid Build Coastguard Worker     void assignUniforms(const vector<BasicUniform> &basicUniforms, uint32_t programGL, Random &rnd);
1102*35238bceSAndroid Build Coastguard Worker     // Compare the uniform values given in values (obtained with glGetUniform*()) with the basicUniform.finalValue values.
1103*35238bceSAndroid Build Coastguard Worker     bool compareUniformValues(const vector<VarValue> &values, const vector<BasicUniform> &basicUniforms);
1104*35238bceSAndroid Build Coastguard Worker     // Render and check that all pixels are white (i.e. all uniform comparisons passed).
1105*35238bceSAndroid Build Coastguard Worker     bool renderTest(const vector<BasicUniform> &basicUniforms, const ShaderProgram &program, Random &rnd);
1106*35238bceSAndroid Build Coastguard Worker 
1107*35238bceSAndroid Build Coastguard Worker     virtual bool test(const vector<BasicUniform> &basicUniforms,
1108*35238bceSAndroid Build Coastguard Worker                       const vector<BasicUniformReportRef> &basicUniformReportsRef, const ShaderProgram &program,
1109*35238bceSAndroid Build Coastguard Worker                       Random &rnd) = 0;
1110*35238bceSAndroid Build Coastguard Worker 
1111*35238bceSAndroid Build Coastguard Worker     const uint32_t m_features;
1112*35238bceSAndroid Build Coastguard Worker     const SharedPtr<const UniformCollection> m_uniformCollection;
1113*35238bceSAndroid Build Coastguard Worker 
1114*35238bceSAndroid Build Coastguard Worker private:
1115*35238bceSAndroid Build Coastguard Worker     static uint32_t randomFeatures(uint32_t seed);
1116*35238bceSAndroid Build Coastguard Worker 
1117*35238bceSAndroid Build Coastguard Worker     // Generates the basic uniforms, based on the uniform with name varName and type varType, in the same manner as are expected
1118*35238bceSAndroid Build Coastguard Worker     // to be returned by glGetActiveUniform(), e.g. generates a name like var[0] for arrays, and recursively generates struct member names.
1119*35238bceSAndroid Build Coastguard Worker     void generateBasicUniforms(vector<BasicUniform> &basicUniformsDst,
1120*35238bceSAndroid Build Coastguard Worker                                vector<BasicUniformReportRef> &basicUniformReportsDst, const glu::VarType &varType,
1121*35238bceSAndroid Build Coastguard Worker                                const char *varName, bool isParentActive, int &samplerUnitCounter, Random &rnd) const;
1122*35238bceSAndroid Build Coastguard Worker 
1123*35238bceSAndroid Build Coastguard Worker     void writeUniformDefinitions(std::ostringstream &dst) const;
1124*35238bceSAndroid Build Coastguard Worker     void writeUniformCompareExpr(std::ostringstream &dst, const BasicUniform &uniform) const;
1125*35238bceSAndroid Build Coastguard Worker     void writeUniformComparisons(std::ostringstream &dst, const vector<BasicUniform> &basicUniforms,
1126*35238bceSAndroid Build Coastguard Worker                                  const char *variableName) const;
1127*35238bceSAndroid Build Coastguard Worker 
1128*35238bceSAndroid Build Coastguard Worker     string generateVertexSource(const vector<BasicUniform> &basicUniforms) const;
1129*35238bceSAndroid Build Coastguard Worker     string generateFragmentSource(const vector<BasicUniform> &basicUniforms) const;
1130*35238bceSAndroid Build Coastguard Worker 
1131*35238bceSAndroid Build Coastguard Worker     void setupTexture(const VarValue &value);
1132*35238bceSAndroid Build Coastguard Worker 
1133*35238bceSAndroid Build Coastguard Worker     const CaseShaderType m_caseShaderType;
1134*35238bceSAndroid Build Coastguard Worker 
1135*35238bceSAndroid Build Coastguard Worker     vector<glu::Texture2D *> m_textures2d;
1136*35238bceSAndroid Build Coastguard Worker     vector<glu::TextureCube *> m_texturesCube;
1137*35238bceSAndroid Build Coastguard Worker     vector<uint32_t> m_filledTextureUnits;
1138*35238bceSAndroid Build Coastguard Worker };
1139*35238bceSAndroid Build Coastguard Worker 
randomFeatures(const uint32_t seed)1140*35238bceSAndroid Build Coastguard Worker uint32_t UniformCase::randomFeatures(const uint32_t seed)
1141*35238bceSAndroid Build Coastguard Worker {
1142*35238bceSAndroid Build Coastguard Worker     static const uint32_t arrayUsageChoices[]     = {0, FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX};
1143*35238bceSAndroid Build Coastguard Worker     static const uint32_t uniformFuncChoices[]    = {0, FEATURE_UNIFORMFUNC_VALUE};
1144*35238bceSAndroid Build Coastguard Worker     static const uint32_t matrixModeChoices[]     = {0, FEATURE_MATRIXMODE_ROWMAJOR};
1145*35238bceSAndroid Build Coastguard Worker     static const uint32_t arrayAssignChoices[]    = {0, FEATURE_ARRAYASSIGN_FULL, FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO};
1146*35238bceSAndroid Build Coastguard Worker     static const uint32_t uniformUsageChoices[]   = {0, FEATURE_UNIFORMUSAGE_EVERY_OTHER};
1147*35238bceSAndroid Build Coastguard Worker     static const uint32_t booleanApiTypeChoices[] = {0, FEATURE_BOOLEANAPITYPE_INT, FEATURE_BOOLEANAPITYPE_UINT};
1148*35238bceSAndroid Build Coastguard Worker     static const uint32_t uniformValueChoices[]   = {0, FEATURE_UNIFORMVALUE_ZERO};
1149*35238bceSAndroid Build Coastguard Worker 
1150*35238bceSAndroid Build Coastguard Worker     Random rnd(seed);
1151*35238bceSAndroid Build Coastguard Worker 
1152*35238bceSAndroid Build Coastguard Worker     uint32_t result = 0;
1153*35238bceSAndroid Build Coastguard Worker 
1154*35238bceSAndroid Build Coastguard Worker #define ARRAY_CHOICE(ARR) ((ARR)[rnd.getInt(0, DE_LENGTH_OF_ARRAY(ARR) - 1)])
1155*35238bceSAndroid Build Coastguard Worker 
1156*35238bceSAndroid Build Coastguard Worker     result |= ARRAY_CHOICE(arrayUsageChoices);
1157*35238bceSAndroid Build Coastguard Worker     result |= ARRAY_CHOICE(uniformFuncChoices);
1158*35238bceSAndroid Build Coastguard Worker     result |= ARRAY_CHOICE(matrixModeChoices);
1159*35238bceSAndroid Build Coastguard Worker     result |= ARRAY_CHOICE(arrayAssignChoices);
1160*35238bceSAndroid Build Coastguard Worker     result |= ARRAY_CHOICE(uniformUsageChoices);
1161*35238bceSAndroid Build Coastguard Worker     result |= ARRAY_CHOICE(booleanApiTypeChoices);
1162*35238bceSAndroid Build Coastguard Worker     result |= ARRAY_CHOICE(uniformValueChoices);
1163*35238bceSAndroid Build Coastguard Worker 
1164*35238bceSAndroid Build Coastguard Worker #undef ARRAY_CHOICE
1165*35238bceSAndroid Build Coastguard Worker 
1166*35238bceSAndroid Build Coastguard Worker     return result;
1167*35238bceSAndroid Build Coastguard Worker }
1168*35238bceSAndroid Build Coastguard Worker 
UniformCase(Context & context,const char * const name,const char * const description,const CaseShaderType caseShaderType,const SharedPtr<const UniformCollection> & uniformCollection,const uint32_t features)1169*35238bceSAndroid Build Coastguard Worker UniformCase::UniformCase(Context &context, const char *const name, const char *const description,
1170*35238bceSAndroid Build Coastguard Worker                          const CaseShaderType caseShaderType,
1171*35238bceSAndroid Build Coastguard Worker                          const SharedPtr<const UniformCollection> &uniformCollection, const uint32_t features)
1172*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
1173*35238bceSAndroid Build Coastguard Worker     , CallLogWrapper(context.getRenderContext().getFunctions(), m_testCtx.getLog())
1174*35238bceSAndroid Build Coastguard Worker     , m_features(features)
1175*35238bceSAndroid Build Coastguard Worker     , m_uniformCollection(uniformCollection)
1176*35238bceSAndroid Build Coastguard Worker     , m_caseShaderType(caseShaderType)
1177*35238bceSAndroid Build Coastguard Worker {
1178*35238bceSAndroid Build Coastguard Worker }
1179*35238bceSAndroid Build Coastguard Worker 
UniformCase(Context & context,const char * name,const char * description,const uint32_t seed)1180*35238bceSAndroid Build Coastguard Worker UniformCase::UniformCase(Context &context, const char *name, const char *description, const uint32_t seed)
1181*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
1182*35238bceSAndroid Build Coastguard Worker     , CallLogWrapper(context.getRenderContext().getFunctions(), m_testCtx.getLog())
1183*35238bceSAndroid Build Coastguard Worker     , m_features(randomFeatures(seed))
1184*35238bceSAndroid Build Coastguard Worker     , m_uniformCollection(UniformCollection::random(seed))
1185*35238bceSAndroid Build Coastguard Worker     , m_caseShaderType(randomCaseShaderType(seed))
1186*35238bceSAndroid Build Coastguard Worker {
1187*35238bceSAndroid Build Coastguard Worker }
1188*35238bceSAndroid Build Coastguard Worker 
init(void)1189*35238bceSAndroid Build Coastguard Worker void UniformCase::init(void)
1190*35238bceSAndroid Build Coastguard Worker {
1191*35238bceSAndroid Build Coastguard Worker     {
1192*35238bceSAndroid Build Coastguard Worker         const glw::Functions &funcs         = m_context.getRenderContext().getFunctions();
1193*35238bceSAndroid Build Coastguard Worker         const int numSamplerUniforms        = m_uniformCollection->getNumSamplers();
1194*35238bceSAndroid Build Coastguard Worker         const int vertexTexUnitsRequired    = m_caseShaderType != CASESHADERTYPE_FRAGMENT ? numSamplerUniforms : 0;
1195*35238bceSAndroid Build Coastguard Worker         const int fragmentTexUnitsRequired  = m_caseShaderType != CASESHADERTYPE_VERTEX ? numSamplerUniforms : 0;
1196*35238bceSAndroid Build Coastguard Worker         const int combinedTexUnitsRequired  = vertexTexUnitsRequired + fragmentTexUnitsRequired;
1197*35238bceSAndroid Build Coastguard Worker         const int vertexTexUnitsSupported   = getGLInt(funcs, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
1198*35238bceSAndroid Build Coastguard Worker         const int fragmentTexUnitsSupported = getGLInt(funcs, GL_MAX_TEXTURE_IMAGE_UNITS);
1199*35238bceSAndroid Build Coastguard Worker         const int combinedTexUnitsSupported = getGLInt(funcs, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
1200*35238bceSAndroid Build Coastguard Worker 
1201*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numSamplerUniforms <= MAX_NUM_SAMPLER_UNIFORMS);
1202*35238bceSAndroid Build Coastguard Worker 
1203*35238bceSAndroid Build Coastguard Worker         if (vertexTexUnitsRequired > vertexTexUnitsSupported)
1204*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError(de::toString(vertexTexUnitsRequired) + " vertex texture units required, " +
1205*35238bceSAndroid Build Coastguard Worker                                          de::toString(vertexTexUnitsSupported) + " supported");
1206*35238bceSAndroid Build Coastguard Worker         if (fragmentTexUnitsRequired > fragmentTexUnitsSupported)
1207*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError(de::toString(fragmentTexUnitsRequired) + " fragment texture units required, " +
1208*35238bceSAndroid Build Coastguard Worker                                          de::toString(fragmentTexUnitsSupported) + " supported");
1209*35238bceSAndroid Build Coastguard Worker         if (combinedTexUnitsRequired > combinedTexUnitsSupported)
1210*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError(de::toString(combinedTexUnitsRequired) + " combined texture units required, " +
1211*35238bceSAndroid Build Coastguard Worker                                          de::toString(combinedTexUnitsSupported) + " supported");
1212*35238bceSAndroid Build Coastguard Worker     }
1213*35238bceSAndroid Build Coastguard Worker 
1214*35238bceSAndroid Build Coastguard Worker     enableLogging(true);
1215*35238bceSAndroid Build Coastguard Worker }
1216*35238bceSAndroid Build Coastguard Worker 
deinit(void)1217*35238bceSAndroid Build Coastguard Worker void UniformCase::deinit(void)
1218*35238bceSAndroid Build Coastguard Worker {
1219*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)m_textures2d.size(); i++)
1220*35238bceSAndroid Build Coastguard Worker         delete m_textures2d[i];
1221*35238bceSAndroid Build Coastguard Worker     m_textures2d.clear();
1222*35238bceSAndroid Build Coastguard Worker 
1223*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)m_texturesCube.size(); i++)
1224*35238bceSAndroid Build Coastguard Worker         delete m_texturesCube[i];
1225*35238bceSAndroid Build Coastguard Worker     m_texturesCube.clear();
1226*35238bceSAndroid Build Coastguard Worker 
1227*35238bceSAndroid Build Coastguard Worker     m_filledTextureUnits.clear();
1228*35238bceSAndroid Build Coastguard Worker }
1229*35238bceSAndroid Build Coastguard Worker 
~UniformCase(void)1230*35238bceSAndroid Build Coastguard Worker UniformCase::~UniformCase(void)
1231*35238bceSAndroid Build Coastguard Worker {
1232*35238bceSAndroid Build Coastguard Worker     UniformCase::deinit();
1233*35238bceSAndroid Build Coastguard Worker }
1234*35238bceSAndroid Build Coastguard Worker 
generateBasicUniforms(vector<BasicUniform> & basicUniformsDst,vector<BasicUniformReportRef> & basicUniformReportsDst,const glu::VarType & varType,const char * const varName,const bool isParentActive,int & samplerUnitCounter,Random & rnd) const1235*35238bceSAndroid Build Coastguard Worker void UniformCase::generateBasicUniforms(vector<BasicUniform> &basicUniformsDst,
1236*35238bceSAndroid Build Coastguard Worker                                         vector<BasicUniformReportRef> &basicUniformReportsDst,
1237*35238bceSAndroid Build Coastguard Worker                                         const glu::VarType &varType, const char *const varName,
1238*35238bceSAndroid Build Coastguard Worker                                         const bool isParentActive, int &samplerUnitCounter, Random &rnd) const
1239*35238bceSAndroid Build Coastguard Worker {
1240*35238bceSAndroid Build Coastguard Worker     if (varType.isBasicType())
1241*35238bceSAndroid Build Coastguard Worker     {
1242*35238bceSAndroid Build Coastguard Worker         const bool isActive =
1243*35238bceSAndroid Build Coastguard Worker             isParentActive && (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.size() % 2 == 0 : true);
1244*35238bceSAndroid Build Coastguard Worker         const glu::DataType type = varType.getBasicType();
1245*35238bceSAndroid Build Coastguard Worker         const VarValue value     = m_features & FEATURE_UNIFORMVALUE_ZERO ? generateZeroVarValue(type) :
1246*35238bceSAndroid Build Coastguard Worker                                    glu::isDataTypeSampler(type) ? generateRandomVarValue(type, rnd, samplerUnitCounter++) :
1247*35238bceSAndroid Build Coastguard Worker                                                                   generateRandomVarValue(varType.getBasicType(), rnd);
1248*35238bceSAndroid Build Coastguard Worker 
1249*35238bceSAndroid Build Coastguard Worker         basicUniformsDst.push_back(BasicUniform(varName, varType.getBasicType(), isActive, value));
1250*35238bceSAndroid Build Coastguard Worker         basicUniformReportsDst.push_back(BasicUniformReportRef(varName, varType.getBasicType(), isActive));
1251*35238bceSAndroid Build Coastguard Worker     }
1252*35238bceSAndroid Build Coastguard Worker     else if (varType.isArrayType())
1253*35238bceSAndroid Build Coastguard Worker     {
1254*35238bceSAndroid Build Coastguard Worker         const int size             = varType.getArraySize();
1255*35238bceSAndroid Build Coastguard Worker         const string arrayRootName = string("") + varName + "[0]";
1256*35238bceSAndroid Build Coastguard Worker         vector<bool> isElemActive;
1257*35238bceSAndroid Build Coastguard Worker 
1258*35238bceSAndroid Build Coastguard Worker         for (int elemNdx = 0; elemNdx < varType.getArraySize(); elemNdx++)
1259*35238bceSAndroid Build Coastguard Worker         {
1260*35238bceSAndroid Build Coastguard Worker             const string indexedName = string("") + varName + "[" + de::toString(elemNdx) + "]";
1261*35238bceSAndroid Build Coastguard Worker             const bool isCurElemActive =
1262*35238bceSAndroid Build Coastguard Worker                 isParentActive &&
1263*35238bceSAndroid Build Coastguard Worker                 (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.size() % 2 == 0 : true) &&
1264*35238bceSAndroid Build Coastguard Worker                 (m_features & FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX ? elemNdx == size / 2 : true);
1265*35238bceSAndroid Build Coastguard Worker 
1266*35238bceSAndroid Build Coastguard Worker             isElemActive.push_back(isCurElemActive);
1267*35238bceSAndroid Build Coastguard Worker 
1268*35238bceSAndroid Build Coastguard Worker             if (varType.getElementType().isBasicType())
1269*35238bceSAndroid Build Coastguard Worker             {
1270*35238bceSAndroid Build Coastguard Worker                 // \note We don't want separate entries in basicUniformReportsDst for elements of basic-type arrays.
1271*35238bceSAndroid Build Coastguard Worker                 const glu::DataType elemBasicType = varType.getElementType().getBasicType();
1272*35238bceSAndroid Build Coastguard Worker                 const VarValue value              = m_features & FEATURE_UNIFORMVALUE_ZERO ?
1273*35238bceSAndroid Build Coastguard Worker                                                         generateZeroVarValue(elemBasicType) :
1274*35238bceSAndroid Build Coastguard Worker                                                     glu::isDataTypeSampler(elemBasicType) ?
1275*35238bceSAndroid Build Coastguard Worker                                                         generateRandomVarValue(elemBasicType, rnd, samplerUnitCounter++) :
1276*35238bceSAndroid Build Coastguard Worker                                                         generateRandomVarValue(elemBasicType, rnd);
1277*35238bceSAndroid Build Coastguard Worker 
1278*35238bceSAndroid Build Coastguard Worker                 basicUniformsDst.push_back(BasicUniform(indexedName.c_str(), elemBasicType, isCurElemActive, value,
1279*35238bceSAndroid Build Coastguard Worker                                                         arrayRootName.c_str(), elemNdx, size));
1280*35238bceSAndroid Build Coastguard Worker             }
1281*35238bceSAndroid Build Coastguard Worker             else
1282*35238bceSAndroid Build Coastguard Worker                 generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, varType.getElementType(),
1283*35238bceSAndroid Build Coastguard Worker                                       indexedName.c_str(), isCurElemActive, samplerUnitCounter, rnd);
1284*35238bceSAndroid Build Coastguard Worker         }
1285*35238bceSAndroid Build Coastguard Worker 
1286*35238bceSAndroid Build Coastguard Worker         if (varType.getElementType().isBasicType())
1287*35238bceSAndroid Build Coastguard Worker         {
1288*35238bceSAndroid Build Coastguard Worker             int minSize;
1289*35238bceSAndroid Build Coastguard Worker             for (minSize = varType.getArraySize(); minSize > 0 && !isElemActive[minSize - 1]; minSize--)
1290*35238bceSAndroid Build Coastguard Worker                 ;
1291*35238bceSAndroid Build Coastguard Worker 
1292*35238bceSAndroid Build Coastguard Worker             basicUniformReportsDst.push_back(BasicUniformReportRef(arrayRootName.c_str(), minSize, size,
1293*35238bceSAndroid Build Coastguard Worker                                                                    varType.getElementType().getBasicType(),
1294*35238bceSAndroid Build Coastguard Worker                                                                    isParentActive && minSize > 0));
1295*35238bceSAndroid Build Coastguard Worker         }
1296*35238bceSAndroid Build Coastguard Worker     }
1297*35238bceSAndroid Build Coastguard Worker     else
1298*35238bceSAndroid Build Coastguard Worker     {
1299*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(varType.isStructType());
1300*35238bceSAndroid Build Coastguard Worker 
1301*35238bceSAndroid Build Coastguard Worker         const StructType &structType = *varType.getStructPtr();
1302*35238bceSAndroid Build Coastguard Worker 
1303*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < structType.getNumMembers(); i++)
1304*35238bceSAndroid Build Coastguard Worker         {
1305*35238bceSAndroid Build Coastguard Worker             const glu::StructMember &member = structType.getMember(i);
1306*35238bceSAndroid Build Coastguard Worker             const string memberFullName     = string("") + varName + "." + member.getName();
1307*35238bceSAndroid Build Coastguard Worker 
1308*35238bceSAndroid Build Coastguard Worker             generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, member.getType(), memberFullName.c_str(),
1309*35238bceSAndroid Build Coastguard Worker                                   isParentActive, samplerUnitCounter, rnd);
1310*35238bceSAndroid Build Coastguard Worker         }
1311*35238bceSAndroid Build Coastguard Worker     }
1312*35238bceSAndroid Build Coastguard Worker }
1313*35238bceSAndroid Build Coastguard Worker 
writeUniformDefinitions(std::ostringstream & dst) const1314*35238bceSAndroid Build Coastguard Worker void UniformCase::writeUniformDefinitions(std::ostringstream &dst) const
1315*35238bceSAndroid Build Coastguard Worker {
1316*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)m_uniformCollection->getNumStructTypes(); i++)
1317*35238bceSAndroid Build Coastguard Worker         dst << glu::declare(m_uniformCollection->getStructType(i)) << ";\n";
1318*35238bceSAndroid Build Coastguard Worker 
1319*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
1320*35238bceSAndroid Build Coastguard Worker         dst << "uniform "
1321*35238bceSAndroid Build Coastguard Worker             << glu::declare(m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str())
1322*35238bceSAndroid Build Coastguard Worker             << ";\n";
1323*35238bceSAndroid Build Coastguard Worker 
1324*35238bceSAndroid Build Coastguard Worker     dst << "\n";
1325*35238bceSAndroid Build Coastguard Worker 
1326*35238bceSAndroid Build Coastguard Worker     {
1327*35238bceSAndroid Build Coastguard Worker         static const struct
1328*35238bceSAndroid Build Coastguard Worker         {
1329*35238bceSAndroid Build Coastguard Worker             dataTypePredicate requiringTypes[2];
1330*35238bceSAndroid Build Coastguard Worker             const char *definition;
1331*35238bceSAndroid Build Coastguard Worker         } compareFuncs[] = {
1332*35238bceSAndroid Build Coastguard Worker             {{glu::isDataTypeFloatOrVec, glu::isDataTypeMatrix},
1333*35238bceSAndroid Build Coastguard Worker              "mediump float compare_float    (mediump float a, mediump float b)  { return abs(a - b) < 0.05 ? 1.0 : "
1334*35238bceSAndroid Build Coastguard Worker              "0.0; }"},
1335*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_VEC2>, dataTypeIsMatrixWithNRows<2>},
1336*35238bceSAndroid Build Coastguard Worker              "mediump float compare_vec2     (mediump vec2 a, mediump vec2 b)    { return compare_float(a.x, "
1337*35238bceSAndroid Build Coastguard Worker              "b.x)*compare_float(a.y, b.y); }"},
1338*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_VEC3>, dataTypeIsMatrixWithNRows<3>},
1339*35238bceSAndroid Build Coastguard Worker              "mediump float compare_vec3     (mediump vec3 a, mediump vec3 b)    { return compare_float(a.x, "
1340*35238bceSAndroid Build Coastguard Worker              "b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z); }"},
1341*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_VEC4>, dataTypeIsMatrixWithNRows<4>},
1342*35238bceSAndroid Build Coastguard Worker              "mediump float compare_vec4     (mediump vec4 a, mediump vec4 b)    { return compare_float(a.x, "
1343*35238bceSAndroid Build Coastguard Worker              "b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z)*compare_float(a.w, b.w); }"},
1344*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_MAT2>, dataTypeEquals<glu::TYPE_INVALID>},
1345*35238bceSAndroid Build Coastguard Worker              "mediump float compare_mat2     (mediump mat2 a, mediump mat2 b)    { return compare_vec2(a[0], "
1346*35238bceSAndroid Build Coastguard Worker              "b[0])*compare_vec2(a[1], b[1]); }"},
1347*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_MAT2X3>, dataTypeEquals<glu::TYPE_INVALID>},
1348*35238bceSAndroid Build Coastguard Worker              "mediump float compare_mat2x3   (mediump mat2x3 a, mediump mat2x3 b){ return compare_vec3(a[0], "
1349*35238bceSAndroid Build Coastguard Worker              "b[0])*compare_vec3(a[1], b[1]); }"},
1350*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_MAT2X4>, dataTypeEquals<glu::TYPE_INVALID>},
1351*35238bceSAndroid Build Coastguard Worker              "mediump float compare_mat2x4   (mediump mat2x4 a, mediump mat2x4 b){ return compare_vec4(a[0], "
1352*35238bceSAndroid Build Coastguard Worker              "b[0])*compare_vec4(a[1], b[1]); }"},
1353*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_MAT3X2>, dataTypeEquals<glu::TYPE_INVALID>},
1354*35238bceSAndroid Build Coastguard Worker              "mediump float compare_mat3x2   (mediump mat3x2 a, mediump mat3x2 b){ return compare_vec2(a[0], "
1355*35238bceSAndroid Build Coastguard Worker              "b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2]); }"},
1356*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_MAT3>, dataTypeEquals<glu::TYPE_INVALID>},
1357*35238bceSAndroid Build Coastguard Worker              "mediump float compare_mat3     (mediump mat3 a, mediump mat3 b)    { return compare_vec3(a[0], "
1358*35238bceSAndroid Build Coastguard Worker              "b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2]); }"},
1359*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_MAT3X4>, dataTypeEquals<glu::TYPE_INVALID>},
1360*35238bceSAndroid Build Coastguard Worker              "mediump float compare_mat3x4   (mediump mat3x4 a, mediump mat3x4 b){ return compare_vec4(a[0], "
1361*35238bceSAndroid Build Coastguard Worker              "b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2]); }"},
1362*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_MAT4X2>, dataTypeEquals<glu::TYPE_INVALID>},
1363*35238bceSAndroid Build Coastguard Worker              "mediump float compare_mat4x2   (mediump mat4x2 a, mediump mat4x2 b){ return compare_vec2(a[0], "
1364*35238bceSAndroid Build Coastguard Worker              "b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2])*compare_vec2(a[3], b[3]); }"},
1365*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_MAT4X3>, dataTypeEquals<glu::TYPE_INVALID>},
1366*35238bceSAndroid Build Coastguard Worker              "mediump float compare_mat4x3   (mediump mat4x3 a, mediump mat4x3 b){ return compare_vec3(a[0], "
1367*35238bceSAndroid Build Coastguard Worker              "b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2])*compare_vec3(a[3], b[3]); }"},
1368*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_FLOAT_MAT4>, dataTypeEquals<glu::TYPE_INVALID>},
1369*35238bceSAndroid Build Coastguard Worker              "mediump float compare_mat4     (mediump mat4 a, mediump mat4 b)    { return compare_vec4(a[0], "
1370*35238bceSAndroid Build Coastguard Worker              "b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2])*compare_vec4(a[3], b[3]); }"},
1371*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_INT>, dataTypeEquals<glu::TYPE_INVALID>},
1372*35238bceSAndroid Build Coastguard Worker              "mediump float compare_int      (mediump int a, mediump int b)      { return a == b ? 1.0 : 0.0; }"},
1373*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_INT_VEC2>, dataTypeEquals<glu::TYPE_INVALID>},
1374*35238bceSAndroid Build Coastguard Worker              "mediump float compare_ivec2    (mediump ivec2 a, mediump ivec2 b)  { return a == b ? 1.0 : 0.0; }"},
1375*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_INT_VEC3>, dataTypeEquals<glu::TYPE_INVALID>},
1376*35238bceSAndroid Build Coastguard Worker              "mediump float compare_ivec3    (mediump ivec3 a, mediump ivec3 b)  { return a == b ? 1.0 : 0.0; }"},
1377*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_INT_VEC4>, dataTypeEquals<glu::TYPE_INVALID>},
1378*35238bceSAndroid Build Coastguard Worker              "mediump float compare_ivec4    (mediump ivec4 a, mediump ivec4 b)  { return a == b ? 1.0 : 0.0; }"},
1379*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_UINT>, dataTypeEquals<glu::TYPE_INVALID>},
1380*35238bceSAndroid Build Coastguard Worker              "mediump float compare_uint     (mediump uint a, mediump uint b)    { return a == b ? 1.0 : 0.0; }"},
1381*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_UINT_VEC2>, dataTypeEquals<glu::TYPE_INVALID>},
1382*35238bceSAndroid Build Coastguard Worker              "mediump float compare_uvec2    (mediump uvec2 a, mediump uvec2 b)  { return a == b ? 1.0 : 0.0; }"},
1383*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_UINT_VEC3>, dataTypeEquals<glu::TYPE_INVALID>},
1384*35238bceSAndroid Build Coastguard Worker              "mediump float compare_uvec3    (mediump uvec3 a, mediump uvec3 b)  { return a == b ? 1.0 : 0.0; }"},
1385*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_UINT_VEC4>, dataTypeEquals<glu::TYPE_INVALID>},
1386*35238bceSAndroid Build Coastguard Worker              "mediump float compare_uvec4    (mediump uvec4 a, mediump uvec4 b)  { return a == b ? 1.0 : 0.0; }"},
1387*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_BOOL>, dataTypeEquals<glu::TYPE_INVALID>},
1388*35238bceSAndroid Build Coastguard Worker              "mediump float compare_bool     (bool a, bool b)                    { return a == b ? 1.0 : 0.0; }"},
1389*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_BOOL_VEC2>, dataTypeEquals<glu::TYPE_INVALID>},
1390*35238bceSAndroid Build Coastguard Worker              "mediump float compare_bvec2    (bvec2 a, bvec2 b)                  { return a == b ? 1.0 : 0.0; }"},
1391*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_BOOL_VEC3>, dataTypeEquals<glu::TYPE_INVALID>},
1392*35238bceSAndroid Build Coastguard Worker              "mediump float compare_bvec3    (bvec3 a, bvec3 b)                  { return a == b ? 1.0 : 0.0; }"},
1393*35238bceSAndroid Build Coastguard Worker             {{dataTypeEquals<glu::TYPE_BOOL_VEC4>, dataTypeEquals<glu::TYPE_INVALID>},
1394*35238bceSAndroid Build Coastguard Worker              "mediump float compare_bvec4    (bvec4 a, bvec4 b)                  { return a == b ? 1.0 : 0.0; }"}};
1395*35238bceSAndroid Build Coastguard Worker 
1396*35238bceSAndroid Build Coastguard Worker         const vector<glu::DataType> samplerTypes = m_uniformCollection->getSamplerTypes();
1397*35238bceSAndroid Build Coastguard Worker 
1398*35238bceSAndroid Build Coastguard Worker         for (int compFuncNdx = 0; compFuncNdx < DE_LENGTH_OF_ARRAY(compareFuncs); compFuncNdx++)
1399*35238bceSAndroid Build Coastguard Worker         {
1400*35238bceSAndroid Build Coastguard Worker             const dataTypePredicate(&typeReq)[2] = compareFuncs[compFuncNdx].requiringTypes;
1401*35238bceSAndroid Build Coastguard Worker             bool containsTypeSampler             = false;
1402*35238bceSAndroid Build Coastguard Worker 
1403*35238bceSAndroid Build Coastguard Worker             for (int i = 0; i < (int)samplerTypes.size(); i++)
1404*35238bceSAndroid Build Coastguard Worker             {
1405*35238bceSAndroid Build Coastguard Worker                 if (glu::isDataTypeSampler(samplerTypes[i]))
1406*35238bceSAndroid Build Coastguard Worker                 {
1407*35238bceSAndroid Build Coastguard Worker                     const glu::DataType retType = getSamplerLookupReturnType(samplerTypes[i]);
1408*35238bceSAndroid Build Coastguard Worker                     if (typeReq[0](retType) || typeReq[1](retType))
1409*35238bceSAndroid Build Coastguard Worker                     {
1410*35238bceSAndroid Build Coastguard Worker                         containsTypeSampler = true;
1411*35238bceSAndroid Build Coastguard Worker                         break;
1412*35238bceSAndroid Build Coastguard Worker                     }
1413*35238bceSAndroid Build Coastguard Worker                 }
1414*35238bceSAndroid Build Coastguard Worker             }
1415*35238bceSAndroid Build Coastguard Worker 
1416*35238bceSAndroid Build Coastguard Worker             if (containsTypeSampler || m_uniformCollection->containsMatchingBasicType(typeReq[0]) ||
1417*35238bceSAndroid Build Coastguard Worker                 m_uniformCollection->containsMatchingBasicType(typeReq[1]))
1418*35238bceSAndroid Build Coastguard Worker                 dst << compareFuncs[compFuncNdx].definition << "\n";
1419*35238bceSAndroid Build Coastguard Worker         }
1420*35238bceSAndroid Build Coastguard Worker     }
1421*35238bceSAndroid Build Coastguard Worker }
1422*35238bceSAndroid Build Coastguard Worker 
writeUniformCompareExpr(std::ostringstream & dst,const BasicUniform & uniform) const1423*35238bceSAndroid Build Coastguard Worker void UniformCase::writeUniformCompareExpr(std::ostringstream &dst, const BasicUniform &uniform) const
1424*35238bceSAndroid Build Coastguard Worker {
1425*35238bceSAndroid Build Coastguard Worker     if (glu::isDataTypeSampler(uniform.type))
1426*35238bceSAndroid Build Coastguard Worker         dst << "compare_" << glu::getDataTypeName(getSamplerLookupReturnType(uniform.type)) << "(texture("
1427*35238bceSAndroid Build Coastguard Worker             << uniform.name << ", vec" << getSamplerNumLookupDimensions(uniform.type) << "(0.0))";
1428*35238bceSAndroid Build Coastguard Worker     else
1429*35238bceSAndroid Build Coastguard Worker         dst << "compare_" << glu::getDataTypeName(uniform.type) << "(" << uniform.name;
1430*35238bceSAndroid Build Coastguard Worker 
1431*35238bceSAndroid Build Coastguard Worker     dst << ", " << shaderVarValueStr(uniform.finalValue) << ")";
1432*35238bceSAndroid Build Coastguard Worker }
1433*35238bceSAndroid Build Coastguard Worker 
writeUniformComparisons(std::ostringstream & dst,const vector<BasicUniform> & basicUniforms,const char * const variableName) const1434*35238bceSAndroid Build Coastguard Worker void UniformCase::writeUniformComparisons(std::ostringstream &dst, const vector<BasicUniform> &basicUniforms,
1435*35238bceSAndroid Build Coastguard Worker                                           const char *const variableName) const
1436*35238bceSAndroid Build Coastguard Worker {
1437*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)basicUniforms.size(); i++)
1438*35238bceSAndroid Build Coastguard Worker     {
1439*35238bceSAndroid Build Coastguard Worker         const BasicUniform &unif = basicUniforms[i];
1440*35238bceSAndroid Build Coastguard Worker 
1441*35238bceSAndroid Build Coastguard Worker         if (unif.isUsedInShader)
1442*35238bceSAndroid Build Coastguard Worker         {
1443*35238bceSAndroid Build Coastguard Worker             dst << "\t" << variableName << " *= ";
1444*35238bceSAndroid Build Coastguard Worker             writeUniformCompareExpr(dst, basicUniforms[i]);
1445*35238bceSAndroid Build Coastguard Worker             dst << ";\n";
1446*35238bceSAndroid Build Coastguard Worker         }
1447*35238bceSAndroid Build Coastguard Worker         else
1448*35238bceSAndroid Build Coastguard Worker             dst << "\t// UNUSED: " << basicUniforms[i].name << "\n";
1449*35238bceSAndroid Build Coastguard Worker     }
1450*35238bceSAndroid Build Coastguard Worker }
1451*35238bceSAndroid Build Coastguard Worker 
generateVertexSource(const vector<BasicUniform> & basicUniforms) const1452*35238bceSAndroid Build Coastguard Worker string UniformCase::generateVertexSource(const vector<BasicUniform> &basicUniforms) const
1453*35238bceSAndroid Build Coastguard Worker {
1454*35238bceSAndroid Build Coastguard Worker     const bool isVertexCase = m_caseShaderType == CASESHADERTYPE_VERTEX || m_caseShaderType == CASESHADERTYPE_BOTH;
1455*35238bceSAndroid Build Coastguard Worker     std::ostringstream result;
1456*35238bceSAndroid Build Coastguard Worker 
1457*35238bceSAndroid Build Coastguard Worker     result << "#version 300 es\n"
1458*35238bceSAndroid Build Coastguard Worker               "in highp vec4 a_position;\n"
1459*35238bceSAndroid Build Coastguard Worker               "out mediump float v_vtxOut;\n"
1460*35238bceSAndroid Build Coastguard Worker               "\n";
1461*35238bceSAndroid Build Coastguard Worker 
1462*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
1463*35238bceSAndroid Build Coastguard Worker         writeUniformDefinitions(result);
1464*35238bceSAndroid Build Coastguard Worker 
1465*35238bceSAndroid Build Coastguard Worker     result << "\n"
1466*35238bceSAndroid Build Coastguard Worker               "void main (void)\n"
1467*35238bceSAndroid Build Coastguard Worker               "{\n"
1468*35238bceSAndroid Build Coastguard Worker               "    gl_Position = a_position;\n"
1469*35238bceSAndroid Build Coastguard Worker               "    v_vtxOut = 1.0;\n";
1470*35238bceSAndroid Build Coastguard Worker 
1471*35238bceSAndroid Build Coastguard Worker     if (isVertexCase)
1472*35238bceSAndroid Build Coastguard Worker         writeUniformComparisons(result, basicUniforms, "v_vtxOut");
1473*35238bceSAndroid Build Coastguard Worker 
1474*35238bceSAndroid Build Coastguard Worker     result << "}\n";
1475*35238bceSAndroid Build Coastguard Worker 
1476*35238bceSAndroid Build Coastguard Worker     return result.str();
1477*35238bceSAndroid Build Coastguard Worker }
1478*35238bceSAndroid Build Coastguard Worker 
generateFragmentSource(const vector<BasicUniform> & basicUniforms) const1479*35238bceSAndroid Build Coastguard Worker string UniformCase::generateFragmentSource(const vector<BasicUniform> &basicUniforms) const
1480*35238bceSAndroid Build Coastguard Worker {
1481*35238bceSAndroid Build Coastguard Worker     const bool isFragmentCase = m_caseShaderType == CASESHADERTYPE_FRAGMENT || m_caseShaderType == CASESHADERTYPE_BOTH;
1482*35238bceSAndroid Build Coastguard Worker     std::ostringstream result;
1483*35238bceSAndroid Build Coastguard Worker 
1484*35238bceSAndroid Build Coastguard Worker     result << "#version 300 es\n"
1485*35238bceSAndroid Build Coastguard Worker               "in mediump float v_vtxOut;\n"
1486*35238bceSAndroid Build Coastguard Worker               "\n";
1487*35238bceSAndroid Build Coastguard Worker 
1488*35238bceSAndroid Build Coastguard Worker     if (isFragmentCase)
1489*35238bceSAndroid Build Coastguard Worker         writeUniformDefinitions(result);
1490*35238bceSAndroid Build Coastguard Worker 
1491*35238bceSAndroid Build Coastguard Worker     result << "\n"
1492*35238bceSAndroid Build Coastguard Worker               "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
1493*35238bceSAndroid Build Coastguard Worker               "\n"
1494*35238bceSAndroid Build Coastguard Worker               "void main (void)\n"
1495*35238bceSAndroid Build Coastguard Worker               "{\n"
1496*35238bceSAndroid Build Coastguard Worker               "    mediump float result = v_vtxOut;\n";
1497*35238bceSAndroid Build Coastguard Worker 
1498*35238bceSAndroid Build Coastguard Worker     if (isFragmentCase)
1499*35238bceSAndroid Build Coastguard Worker         writeUniformComparisons(result, basicUniforms, "result");
1500*35238bceSAndroid Build Coastguard Worker 
1501*35238bceSAndroid Build Coastguard Worker     result << "    dEQP_FragColor = vec4(result, result, result, 1.0);\n"
1502*35238bceSAndroid Build Coastguard Worker               "}\n";
1503*35238bceSAndroid Build Coastguard Worker 
1504*35238bceSAndroid Build Coastguard Worker     return result.str();
1505*35238bceSAndroid Build Coastguard Worker }
1506*35238bceSAndroid Build Coastguard Worker 
setupTexture(const VarValue & value)1507*35238bceSAndroid Build Coastguard Worker void UniformCase::setupTexture(const VarValue &value)
1508*35238bceSAndroid Build Coastguard Worker {
1509*35238bceSAndroid Build Coastguard Worker     // \note No handling for samplers other than 2D or cube.
1510*35238bceSAndroid Build Coastguard Worker 
1511*35238bceSAndroid Build Coastguard Worker     enableLogging(false);
1512*35238bceSAndroid Build Coastguard Worker 
1513*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getSamplerLookupReturnType(value.type) == glu::TYPE_FLOAT_VEC4);
1514*35238bceSAndroid Build Coastguard Worker 
1515*35238bceSAndroid Build Coastguard Worker     const int width       = 32;
1516*35238bceSAndroid Build Coastguard Worker     const int height      = 32;
1517*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 color = vec4FromPtr(&value.val.samplerV.fillColor.floatV[0]);
1518*35238bceSAndroid Build Coastguard Worker 
1519*35238bceSAndroid Build Coastguard Worker     if (value.type == glu::TYPE_SAMPLER_2D)
1520*35238bceSAndroid Build Coastguard Worker     {
1521*35238bceSAndroid Build Coastguard Worker         glu::Texture2D *texture =
1522*35238bceSAndroid Build Coastguard Worker             new glu::Texture2D(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width, height);
1523*35238bceSAndroid Build Coastguard Worker         tcu::Texture2D &refTexture = texture->getRefTexture();
1524*35238bceSAndroid Build Coastguard Worker         m_textures2d.push_back(texture);
1525*35238bceSAndroid Build Coastguard Worker 
1526*35238bceSAndroid Build Coastguard Worker         refTexture.allocLevel(0);
1527*35238bceSAndroid Build Coastguard Worker         fillWithColor(refTexture.getLevel(0), color);
1528*35238bceSAndroid Build Coastguard Worker 
1529*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
1530*35238bceSAndroid Build Coastguard Worker         m_filledTextureUnits.push_back(value.val.samplerV.unit);
1531*35238bceSAndroid Build Coastguard Worker         texture->upload();
1532*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
1533*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
1534*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
1535*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
1536*35238bceSAndroid Build Coastguard Worker     }
1537*35238bceSAndroid Build Coastguard Worker     else if (value.type == glu::TYPE_SAMPLER_CUBE)
1538*35238bceSAndroid Build Coastguard Worker     {
1539*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(width == height);
1540*35238bceSAndroid Build Coastguard Worker 
1541*35238bceSAndroid Build Coastguard Worker         glu::TextureCube *texture =
1542*35238bceSAndroid Build Coastguard Worker             new glu::TextureCube(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width);
1543*35238bceSAndroid Build Coastguard Worker         tcu::TextureCube &refTexture = texture->getRefTexture();
1544*35238bceSAndroid Build Coastguard Worker         m_texturesCube.push_back(texture);
1545*35238bceSAndroid Build Coastguard Worker 
1546*35238bceSAndroid Build Coastguard Worker         for (int face = 0; face < (int)tcu::CUBEFACE_LAST; face++)
1547*35238bceSAndroid Build Coastguard Worker         {
1548*35238bceSAndroid Build Coastguard Worker             refTexture.allocLevel((tcu::CubeFace)face, 0);
1549*35238bceSAndroid Build Coastguard Worker             fillWithColor(refTexture.getLevelFace(0, (tcu::CubeFace)face), color);
1550*35238bceSAndroid Build Coastguard Worker         }
1551*35238bceSAndroid Build Coastguard Worker 
1552*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
1553*35238bceSAndroid Build Coastguard Worker         m_filledTextureUnits.push_back(value.val.samplerV.unit);
1554*35238bceSAndroid Build Coastguard Worker         texture->upload();
1555*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
1556*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
1557*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
1558*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
1559*35238bceSAndroid Build Coastguard Worker     }
1560*35238bceSAndroid Build Coastguard Worker     else
1561*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1562*35238bceSAndroid Build Coastguard Worker 
1563*35238bceSAndroid Build Coastguard Worker     enableLogging(true);
1564*35238bceSAndroid Build Coastguard Worker }
1565*35238bceSAndroid Build Coastguard Worker 
getActiveUniforms(vector<BasicUniformReportGL> & basicUniformReportsDst,const vector<BasicUniformReportRef> & basicUniformReportsRef,const uint32_t programGL)1566*35238bceSAndroid Build Coastguard Worker bool UniformCase::getActiveUniforms(vector<BasicUniformReportGL> &basicUniformReportsDst,
1567*35238bceSAndroid Build Coastguard Worker                                     const vector<BasicUniformReportRef> &basicUniformReportsRef,
1568*35238bceSAndroid Build Coastguard Worker                                     const uint32_t programGL)
1569*35238bceSAndroid Build Coastguard Worker {
1570*35238bceSAndroid Build Coastguard Worker     TestLog &log               = m_testCtx.getLog();
1571*35238bceSAndroid Build Coastguard Worker     GLint numActiveUniforms    = 0;
1572*35238bceSAndroid Build Coastguard Worker     GLint uniformMaxNameLength = 0;
1573*35238bceSAndroid Build Coastguard Worker     vector<char> nameBuffer;
1574*35238bceSAndroid Build Coastguard Worker     bool success = true;
1575*35238bceSAndroid Build Coastguard Worker 
1576*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glGetProgramiv(programGL, GL_ACTIVE_UNIFORMS, &numActiveUniforms));
1577*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "// Number of active uniforms reported: " << numActiveUniforms << TestLog::EndMessage;
1578*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glGetProgramiv(programGL, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformMaxNameLength));
1579*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "// Maximum uniform name length reported: " << uniformMaxNameLength
1580*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
1581*35238bceSAndroid Build Coastguard Worker     nameBuffer.resize(uniformMaxNameLength);
1582*35238bceSAndroid Build Coastguard Worker 
1583*35238bceSAndroid Build Coastguard Worker     for (int unifNdx = 0; unifNdx < numActiveUniforms; unifNdx++)
1584*35238bceSAndroid Build Coastguard Worker     {
1585*35238bceSAndroid Build Coastguard Worker         GLsizei reportedNameLength = 0;
1586*35238bceSAndroid Build Coastguard Worker         GLint reportedSize         = -1;
1587*35238bceSAndroid Build Coastguard Worker         GLenum reportedTypeGL      = GL_NONE;
1588*35238bceSAndroid Build Coastguard Worker 
1589*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glGetActiveUniform(programGL, (GLuint)unifNdx, (GLsizei)uniformMaxNameLength,
1590*35238bceSAndroid Build Coastguard Worker                                           &reportedNameLength, &reportedSize, &reportedTypeGL, &nameBuffer[0]));
1591*35238bceSAndroid Build Coastguard Worker 
1592*35238bceSAndroid Build Coastguard Worker         const glu::DataType reportedType = glu::getDataTypeFromGLType(reportedTypeGL);
1593*35238bceSAndroid Build Coastguard Worker         const string reportedNameStr(&nameBuffer[0]);
1594*35238bceSAndroid Build Coastguard Worker 
1595*35238bceSAndroid Build Coastguard Worker         TCU_CHECK_MSG(reportedType != glu::TYPE_LAST, "Invalid uniform type");
1596*35238bceSAndroid Build Coastguard Worker 
1597*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "// Got name = " << reportedNameStr << ", name length = " << reportedNameLength
1598*35238bceSAndroid Build Coastguard Worker             << ", size = " << reportedSize << ", type = " << glu::getDataTypeName(reportedType) << TestLog::EndMessage;
1599*35238bceSAndroid Build Coastguard Worker 
1600*35238bceSAndroid Build Coastguard Worker         if ((GLsizei)reportedNameStr.length() != reportedNameLength)
1601*35238bceSAndroid Build Coastguard Worker         {
1602*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "// FAILURE: wrong name length reported, should be " << reportedNameStr.length()
1603*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
1604*35238bceSAndroid Build Coastguard Worker             success = false;
1605*35238bceSAndroid Build Coastguard Worker         }
1606*35238bceSAndroid Build Coastguard Worker 
1607*35238bceSAndroid Build Coastguard Worker         if (!deStringBeginsWith(reportedNameStr.c_str(), "gl_")) // Ignore built-in uniforms.
1608*35238bceSAndroid Build Coastguard Worker         {
1609*35238bceSAndroid Build Coastguard Worker             int referenceNdx;
1610*35238bceSAndroid Build Coastguard Worker             for (referenceNdx = 0; referenceNdx < (int)basicUniformReportsRef.size(); referenceNdx++)
1611*35238bceSAndroid Build Coastguard Worker             {
1612*35238bceSAndroid Build Coastguard Worker                 if (basicUniformReportsRef[referenceNdx].name == reportedNameStr)
1613*35238bceSAndroid Build Coastguard Worker                     break;
1614*35238bceSAndroid Build Coastguard Worker             }
1615*35238bceSAndroid Build Coastguard Worker 
1616*35238bceSAndroid Build Coastguard Worker             if (referenceNdx >= (int)basicUniformReportsRef.size())
1617*35238bceSAndroid Build Coastguard Worker             {
1618*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "// FAILURE: invalid non-built-in uniform name reported"
1619*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
1620*35238bceSAndroid Build Coastguard Worker                 success = false;
1621*35238bceSAndroid Build Coastguard Worker             }
1622*35238bceSAndroid Build Coastguard Worker             else
1623*35238bceSAndroid Build Coastguard Worker             {
1624*35238bceSAndroid Build Coastguard Worker                 const BasicUniformReportRef &reference = basicUniformReportsRef[referenceNdx];
1625*35238bceSAndroid Build Coastguard Worker 
1626*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(reference.type != glu::TYPE_LAST);
1627*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader));
1628*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(reference.minSize <= reference.maxSize);
1629*35238bceSAndroid Build Coastguard Worker 
1630*35238bceSAndroid Build Coastguard Worker                 if (BasicUniformReportGL::findWithName(basicUniformReportsDst, reportedNameStr.c_str()) !=
1631*35238bceSAndroid Build Coastguard Worker                     basicUniformReportsDst.end())
1632*35238bceSAndroid Build Coastguard Worker                 {
1633*35238bceSAndroid Build Coastguard Worker                     log << TestLog::Message << "// FAILURE: same uniform name reported twice" << TestLog::EndMessage;
1634*35238bceSAndroid Build Coastguard Worker                     success = false;
1635*35238bceSAndroid Build Coastguard Worker                 }
1636*35238bceSAndroid Build Coastguard Worker 
1637*35238bceSAndroid Build Coastguard Worker                 basicUniformReportsDst.push_back(BasicUniformReportGL(reportedNameStr.c_str(), reportedNameLength,
1638*35238bceSAndroid Build Coastguard Worker                                                                       reportedSize, reportedType, unifNdx));
1639*35238bceSAndroid Build Coastguard Worker 
1640*35238bceSAndroid Build Coastguard Worker                 if (reportedType != reference.type)
1641*35238bceSAndroid Build Coastguard Worker                 {
1642*35238bceSAndroid Build Coastguard Worker                     log << TestLog::Message << "// FAILURE: wrong type reported, should be "
1643*35238bceSAndroid Build Coastguard Worker                         << glu::getDataTypeName(reference.type) << TestLog::EndMessage;
1644*35238bceSAndroid Build Coastguard Worker                     success = false;
1645*35238bceSAndroid Build Coastguard Worker                 }
1646*35238bceSAndroid Build Coastguard Worker                 if (reportedSize < reference.minSize || reportedSize > reference.maxSize)
1647*35238bceSAndroid Build Coastguard Worker                 {
1648*35238bceSAndroid Build Coastguard Worker                     log << TestLog::Message << "// FAILURE: wrong size reported, should be "
1649*35238bceSAndroid Build Coastguard Worker                         << (reference.minSize == reference.maxSize ?
1650*35238bceSAndroid Build Coastguard Worker                                 de::toString(reference.minSize) :
1651*35238bceSAndroid Build Coastguard Worker                                 "in the range [" + de::toString(reference.minSize) + ", " +
1652*35238bceSAndroid Build Coastguard Worker                                     de::toString(reference.maxSize) + "]")
1653*35238bceSAndroid Build Coastguard Worker                         << TestLog::EndMessage;
1654*35238bceSAndroid Build Coastguard Worker 
1655*35238bceSAndroid Build Coastguard Worker                     success = false;
1656*35238bceSAndroid Build Coastguard Worker                 }
1657*35238bceSAndroid Build Coastguard Worker             }
1658*35238bceSAndroid Build Coastguard Worker         }
1659*35238bceSAndroid Build Coastguard Worker     }
1660*35238bceSAndroid Build Coastguard Worker 
1661*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)basicUniformReportsRef.size(); i++)
1662*35238bceSAndroid Build Coastguard Worker     {
1663*35238bceSAndroid Build Coastguard Worker         const BasicUniformReportRef &expected = basicUniformReportsRef[i];
1664*35238bceSAndroid Build Coastguard Worker         if (expected.isUsedInShader &&
1665*35238bceSAndroid Build Coastguard Worker             BasicUniformReportGL::findWithName(basicUniformReportsDst, expected.name.c_str()) ==
1666*35238bceSAndroid Build Coastguard Worker                 basicUniformReportsDst.end())
1667*35238bceSAndroid Build Coastguard Worker         {
1668*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "// FAILURE: uniform with name " << expected.name << " was not reported by GL"
1669*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
1670*35238bceSAndroid Build Coastguard Worker             success = false;
1671*35238bceSAndroid Build Coastguard Worker         }
1672*35238bceSAndroid Build Coastguard Worker     }
1673*35238bceSAndroid Build Coastguard Worker 
1674*35238bceSAndroid Build Coastguard Worker     return success;
1675*35238bceSAndroid Build Coastguard Worker }
1676*35238bceSAndroid Build Coastguard Worker 
getActiveUniformsiv(vector<BasicUniformReportGL> & basicUniformReportsDst,const vector<BasicUniformReportRef> & basicUniformReportsRef,const uint32_t programGL)1677*35238bceSAndroid Build Coastguard Worker bool UniformCase::getActiveUniformsiv(vector<BasicUniformReportGL> &basicUniformReportsDst,
1678*35238bceSAndroid Build Coastguard Worker                                       const vector<BasicUniformReportRef> &basicUniformReportsRef,
1679*35238bceSAndroid Build Coastguard Worker                                       const uint32_t programGL)
1680*35238bceSAndroid Build Coastguard Worker {
1681*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1682*35238bceSAndroid Build Coastguard Worker     vector<string> queryNames(basicUniformReportsRef.size());
1683*35238bceSAndroid Build Coastguard Worker     vector<const char *> queryNamesC(basicUniformReportsRef.size());
1684*35238bceSAndroid Build Coastguard Worker     vector<GLuint> uniformIndices(basicUniformReportsRef.size());
1685*35238bceSAndroid Build Coastguard Worker     vector<uint32_t>
1686*35238bceSAndroid Build Coastguard Worker         validUniformIndices; // This shall have the same contents, and in same order, as uniformIndices, but with GL_INVALID_INDEX entries removed.
1687*35238bceSAndroid Build Coastguard Worker     bool success = true;
1688*35238bceSAndroid Build Coastguard Worker 
1689*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)basicUniformReportsRef.size(); i++)
1690*35238bceSAndroid Build Coastguard Worker     {
1691*35238bceSAndroid Build Coastguard Worker         const string &name = basicUniformReportsRef[i].name;
1692*35238bceSAndroid Build Coastguard Worker         queryNames[i]      = m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && name[name.size() - 1] == ']' ?
1693*35238bceSAndroid Build Coastguard Worker                                  beforeLast(name, '[') :
1694*35238bceSAndroid Build Coastguard Worker                                  name;
1695*35238bceSAndroid Build Coastguard Worker         queryNamesC[i]     = queryNames[i].c_str();
1696*35238bceSAndroid Build Coastguard Worker     }
1697*35238bceSAndroid Build Coastguard Worker 
1698*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(
1699*35238bceSAndroid Build Coastguard Worker         glGetUniformIndices(programGL, (GLsizei)basicUniformReportsRef.size(), &queryNamesC[0], &uniformIndices[0]));
1700*35238bceSAndroid Build Coastguard Worker 
1701*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)uniformIndices.size(); i++)
1702*35238bceSAndroid Build Coastguard Worker     {
1703*35238bceSAndroid Build Coastguard Worker         if (uniformIndices[i] != GL_INVALID_INDEX)
1704*35238bceSAndroid Build Coastguard Worker             validUniformIndices.push_back(uniformIndices[i]);
1705*35238bceSAndroid Build Coastguard Worker         else
1706*35238bceSAndroid Build Coastguard Worker         {
1707*35238bceSAndroid Build Coastguard Worker             if (basicUniformReportsRef[i].isUsedInShader)
1708*35238bceSAndroid Build Coastguard Worker             {
1709*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "// FAILURE: uniform with name " << basicUniformReportsRef[i].name
1710*35238bceSAndroid Build Coastguard Worker                     << " received GL_INVALID_INDEX" << TestLog::EndMessage;
1711*35238bceSAndroid Build Coastguard Worker                 success = false;
1712*35238bceSAndroid Build Coastguard Worker             }
1713*35238bceSAndroid Build Coastguard Worker         }
1714*35238bceSAndroid Build Coastguard Worker     }
1715*35238bceSAndroid Build Coastguard Worker 
1716*35238bceSAndroid Build Coastguard Worker     if (!validUniformIndices.empty())
1717*35238bceSAndroid Build Coastguard Worker     {
1718*35238bceSAndroid Build Coastguard Worker         vector<GLint> uniformNameLengthBuf(validUniformIndices.size());
1719*35238bceSAndroid Build Coastguard Worker         vector<GLint> uniformSizeBuf(validUniformIndices.size());
1720*35238bceSAndroid Build Coastguard Worker         vector<GLint> uniformTypeBuf(validUniformIndices.size());
1721*35238bceSAndroid Build Coastguard Worker 
1722*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glGetActiveUniformsiv(programGL, (GLsizei)validUniformIndices.size(), &validUniformIndices[0],
1723*35238bceSAndroid Build Coastguard Worker                                              GL_UNIFORM_NAME_LENGTH, &uniformNameLengthBuf[0]));
1724*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glGetActiveUniformsiv(programGL, (GLsizei)validUniformIndices.size(), &validUniformIndices[0],
1725*35238bceSAndroid Build Coastguard Worker                                              GL_UNIFORM_SIZE, &uniformSizeBuf[0]));
1726*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glGetActiveUniformsiv(programGL, (GLsizei)validUniformIndices.size(), &validUniformIndices[0],
1727*35238bceSAndroid Build Coastguard Worker                                              GL_UNIFORM_TYPE, &uniformTypeBuf[0]));
1728*35238bceSAndroid Build Coastguard Worker 
1729*35238bceSAndroid Build Coastguard Worker         {
1730*35238bceSAndroid Build Coastguard Worker             int validNdx =
1731*35238bceSAndroid Build Coastguard Worker                 -1; // Keeps the corresponding index to validUniformIndices while unifNdx is the index to uniformIndices.
1732*35238bceSAndroid Build Coastguard Worker             for (int unifNdx = 0; unifNdx < (int)uniformIndices.size(); unifNdx++)
1733*35238bceSAndroid Build Coastguard Worker             {
1734*35238bceSAndroid Build Coastguard Worker                 if (uniformIndices[unifNdx] == GL_INVALID_INDEX)
1735*35238bceSAndroid Build Coastguard Worker                     continue;
1736*35238bceSAndroid Build Coastguard Worker 
1737*35238bceSAndroid Build Coastguard Worker                 validNdx++;
1738*35238bceSAndroid Build Coastguard Worker 
1739*35238bceSAndroid Build Coastguard Worker                 const BasicUniformReportRef &reference = basicUniformReportsRef[unifNdx];
1740*35238bceSAndroid Build Coastguard Worker                 const int reportedIndex                = validUniformIndices[validNdx];
1741*35238bceSAndroid Build Coastguard Worker                 const int reportedNameLength           = (int)uniformNameLengthBuf[validNdx];
1742*35238bceSAndroid Build Coastguard Worker                 const int reportedSize                 = (int)uniformSizeBuf[validNdx];
1743*35238bceSAndroid Build Coastguard Worker                 const glu::DataType reportedType       = glu::getDataTypeFromGLType((uint32_t)uniformTypeBuf[validNdx]);
1744*35238bceSAndroid Build Coastguard Worker 
1745*35238bceSAndroid Build Coastguard Worker                 TCU_CHECK_MSG(reportedType != glu::TYPE_LAST, "Invalid uniform type");
1746*35238bceSAndroid Build Coastguard Worker 
1747*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "// Got name length = " << reportedNameLength << ", size = " << reportedSize
1748*35238bceSAndroid Build Coastguard Worker                     << ", type = " << glu::getDataTypeName(reportedType) << " for the uniform at index "
1749*35238bceSAndroid Build Coastguard Worker                     << reportedIndex << " (" << reference.name << ")" << TestLog::EndMessage;
1750*35238bceSAndroid Build Coastguard Worker 
1751*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(reference.type != glu::TYPE_LAST);
1752*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader));
1753*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(reference.minSize <= reference.maxSize);
1754*35238bceSAndroid Build Coastguard Worker                 basicUniformReportsDst.push_back(BasicUniformReportGL(reference.name.c_str(), reportedNameLength,
1755*35238bceSAndroid Build Coastguard Worker                                                                       reportedSize, reportedType, reportedIndex));
1756*35238bceSAndroid Build Coastguard Worker 
1757*35238bceSAndroid Build Coastguard Worker                 if (reportedNameLength != (int)reference.name.length() + 1)
1758*35238bceSAndroid Build Coastguard Worker                 {
1759*35238bceSAndroid Build Coastguard Worker                     log << TestLog::Message << "// FAILURE: wrong name length reported, should be "
1760*35238bceSAndroid Build Coastguard Worker                         << reference.name.length() + 1 << TestLog::EndMessage;
1761*35238bceSAndroid Build Coastguard Worker                     success = false;
1762*35238bceSAndroid Build Coastguard Worker                 }
1763*35238bceSAndroid Build Coastguard Worker 
1764*35238bceSAndroid Build Coastguard Worker                 if (reportedType != reference.type)
1765*35238bceSAndroid Build Coastguard Worker                 {
1766*35238bceSAndroid Build Coastguard Worker                     log << TestLog::Message << "// FAILURE: wrong type reported, should be "
1767*35238bceSAndroid Build Coastguard Worker                         << glu::getDataTypeName(reference.type) << TestLog::EndMessage;
1768*35238bceSAndroid Build Coastguard Worker                     success = false;
1769*35238bceSAndroid Build Coastguard Worker                 }
1770*35238bceSAndroid Build Coastguard Worker 
1771*35238bceSAndroid Build Coastguard Worker                 if (reportedSize < reference.minSize || reportedSize > reference.maxSize)
1772*35238bceSAndroid Build Coastguard Worker                 {
1773*35238bceSAndroid Build Coastguard Worker                     log << TestLog::Message << "// FAILURE: wrong size reported, should be "
1774*35238bceSAndroid Build Coastguard Worker                         << (reference.minSize == reference.maxSize ?
1775*35238bceSAndroid Build Coastguard Worker                                 de::toString(reference.minSize) :
1776*35238bceSAndroid Build Coastguard Worker                                 "in the range [" + de::toString(reference.minSize) + ", " +
1777*35238bceSAndroid Build Coastguard Worker                                     de::toString(reference.maxSize) + "]")
1778*35238bceSAndroid Build Coastguard Worker                         << TestLog::EndMessage;
1779*35238bceSAndroid Build Coastguard Worker 
1780*35238bceSAndroid Build Coastguard Worker                     success = false;
1781*35238bceSAndroid Build Coastguard Worker                 }
1782*35238bceSAndroid Build Coastguard Worker             }
1783*35238bceSAndroid Build Coastguard Worker         }
1784*35238bceSAndroid Build Coastguard Worker     }
1785*35238bceSAndroid Build Coastguard Worker 
1786*35238bceSAndroid Build Coastguard Worker     return success;
1787*35238bceSAndroid Build Coastguard Worker }
1788*35238bceSAndroid Build Coastguard Worker 
uniformVsUniformsivComparison(const vector<BasicUniformReportGL> & uniformResults,const vector<BasicUniformReportGL> & uniformsivResults)1789*35238bceSAndroid Build Coastguard Worker bool UniformCase::uniformVsUniformsivComparison(const vector<BasicUniformReportGL> &uniformResults,
1790*35238bceSAndroid Build Coastguard Worker                                                 const vector<BasicUniformReportGL> &uniformsivResults)
1791*35238bceSAndroid Build Coastguard Worker {
1792*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1793*35238bceSAndroid Build Coastguard Worker     bool success = true;
1794*35238bceSAndroid Build Coastguard Worker 
1795*35238bceSAndroid Build Coastguard Worker     for (int uniformResultNdx = 0; uniformResultNdx < (int)uniformResults.size(); uniformResultNdx++)
1796*35238bceSAndroid Build Coastguard Worker     {
1797*35238bceSAndroid Build Coastguard Worker         const BasicUniformReportGL &uniformResult = uniformResults[uniformResultNdx];
1798*35238bceSAndroid Build Coastguard Worker         const string &uniformName                 = uniformResult.name;
1799*35238bceSAndroid Build Coastguard Worker         const vector<BasicUniformReportGL>::const_iterator uniformsivResultIt =
1800*35238bceSAndroid Build Coastguard Worker             BasicUniformReportGL::findWithName(uniformsivResults, uniformName.c_str());
1801*35238bceSAndroid Build Coastguard Worker 
1802*35238bceSAndroid Build Coastguard Worker         if (uniformsivResultIt != uniformsivResults.end())
1803*35238bceSAndroid Build Coastguard Worker         {
1804*35238bceSAndroid Build Coastguard Worker             const BasicUniformReportGL &uniformsivResult = *uniformsivResultIt;
1805*35238bceSAndroid Build Coastguard Worker 
1806*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "// Checking uniform " << uniformName << TestLog::EndMessage;
1807*35238bceSAndroid Build Coastguard Worker 
1808*35238bceSAndroid Build Coastguard Worker             if (uniformResult.index != uniformsivResult.index)
1809*35238bceSAndroid Build Coastguard Worker             {
1810*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message
1811*35238bceSAndroid Build Coastguard Worker                     << "// FAILURE: glGetActiveUniform() and glGetUniformIndices() gave different indices for uniform "
1812*35238bceSAndroid Build Coastguard Worker                     << uniformName << TestLog::EndMessage;
1813*35238bceSAndroid Build Coastguard Worker                 success = false;
1814*35238bceSAndroid Build Coastguard Worker             }
1815*35238bceSAndroid Build Coastguard Worker             if (uniformResult.nameLength + 1 != uniformsivResult.nameLength)
1816*35238bceSAndroid Build Coastguard Worker             {
1817*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message
1818*35238bceSAndroid Build Coastguard Worker                     << "// FAILURE: glGetActiveUniform() and glGetActiveUniformsiv() gave incompatible name lengths "
1819*35238bceSAndroid Build Coastguard Worker                        "for uniform "
1820*35238bceSAndroid Build Coastguard Worker                     << uniformName << TestLog::EndMessage;
1821*35238bceSAndroid Build Coastguard Worker                 success = false;
1822*35238bceSAndroid Build Coastguard Worker             }
1823*35238bceSAndroid Build Coastguard Worker             if (uniformResult.size != uniformsivResult.size)
1824*35238bceSAndroid Build Coastguard Worker             {
1825*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message
1826*35238bceSAndroid Build Coastguard Worker                     << "// FAILURE: glGetActiveUniform() and glGetActiveUniformsiv() gave different sizes for uniform "
1827*35238bceSAndroid Build Coastguard Worker                     << uniformName << TestLog::EndMessage;
1828*35238bceSAndroid Build Coastguard Worker                 success = false;
1829*35238bceSAndroid Build Coastguard Worker             }
1830*35238bceSAndroid Build Coastguard Worker             if (uniformResult.type != uniformsivResult.type)
1831*35238bceSAndroid Build Coastguard Worker             {
1832*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message
1833*35238bceSAndroid Build Coastguard Worker                     << "// FAILURE: glGetActiveUniform() and glGetActiveUniformsiv() gave different types for uniform "
1834*35238bceSAndroid Build Coastguard Worker                     << uniformName << TestLog::EndMessage;
1835*35238bceSAndroid Build Coastguard Worker                 success = false;
1836*35238bceSAndroid Build Coastguard Worker             }
1837*35238bceSAndroid Build Coastguard Worker         }
1838*35238bceSAndroid Build Coastguard Worker         else
1839*35238bceSAndroid Build Coastguard Worker         {
1840*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "// FAILURE: uniform " << uniformName
1841*35238bceSAndroid Build Coastguard Worker                 << " was reported active by glGetActiveUniform() but not by glGetUniformIndices()"
1842*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
1843*35238bceSAndroid Build Coastguard Worker             success = false;
1844*35238bceSAndroid Build Coastguard Worker         }
1845*35238bceSAndroid Build Coastguard Worker     }
1846*35238bceSAndroid Build Coastguard Worker 
1847*35238bceSAndroid Build Coastguard Worker     for (int uniformsivResultNdx = 0; uniformsivResultNdx < (int)uniformsivResults.size(); uniformsivResultNdx++)
1848*35238bceSAndroid Build Coastguard Worker     {
1849*35238bceSAndroid Build Coastguard Worker         const BasicUniformReportGL &uniformsivResult = uniformsivResults[uniformsivResultNdx];
1850*35238bceSAndroid Build Coastguard Worker         const string &uniformsivName                 = uniformsivResult.name;
1851*35238bceSAndroid Build Coastguard Worker         const vector<BasicUniformReportGL>::const_iterator uniformsResultIt =
1852*35238bceSAndroid Build Coastguard Worker             BasicUniformReportGL::findWithName(uniformsivResults, uniformsivName.c_str());
1853*35238bceSAndroid Build Coastguard Worker 
1854*35238bceSAndroid Build Coastguard Worker         if (uniformsResultIt == uniformsivResults.end())
1855*35238bceSAndroid Build Coastguard Worker         {
1856*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "// FAILURE: uniform " << uniformsivName
1857*35238bceSAndroid Build Coastguard Worker                 << " was reported active by glGetUniformIndices() but not by glGetActiveUniform()"
1858*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
1859*35238bceSAndroid Build Coastguard Worker             success = false;
1860*35238bceSAndroid Build Coastguard Worker         }
1861*35238bceSAndroid Build Coastguard Worker     }
1862*35238bceSAndroid Build Coastguard Worker 
1863*35238bceSAndroid Build Coastguard Worker     return success;
1864*35238bceSAndroid Build Coastguard Worker }
1865*35238bceSAndroid Build Coastguard Worker 
getUniforms(vector<VarValue> & valuesDst,const vector<BasicUniform> & basicUniforms,const uint32_t programGL)1866*35238bceSAndroid Build Coastguard Worker bool UniformCase::getUniforms(vector<VarValue> &valuesDst, const vector<BasicUniform> &basicUniforms,
1867*35238bceSAndroid Build Coastguard Worker                               const uint32_t programGL)
1868*35238bceSAndroid Build Coastguard Worker {
1869*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1870*35238bceSAndroid Build Coastguard Worker     bool success = true;
1871*35238bceSAndroid Build Coastguard Worker 
1872*35238bceSAndroid Build Coastguard Worker     for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
1873*35238bceSAndroid Build Coastguard Worker     {
1874*35238bceSAndroid Build Coastguard Worker         const BasicUniform &uniform = basicUniforms[unifNdx];
1875*35238bceSAndroid Build Coastguard Worker         const string queryName      = m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ?
1876*35238bceSAndroid Build Coastguard Worker                                           beforeLast(uniform.name, '[') :
1877*35238bceSAndroid Build Coastguard Worker                                           uniform.name;
1878*35238bceSAndroid Build Coastguard Worker         const int location          = glGetUniformLocation(programGL, queryName.c_str());
1879*35238bceSAndroid Build Coastguard Worker         const int size              = glu::getDataTypeScalarSize(uniform.type);
1880*35238bceSAndroid Build Coastguard Worker         VarValue value;
1881*35238bceSAndroid Build Coastguard Worker 
1882*35238bceSAndroid Build Coastguard Worker         deMemset(&value, 0xcd, sizeof(value)); // Initialize to known garbage.
1883*35238bceSAndroid Build Coastguard Worker 
1884*35238bceSAndroid Build Coastguard Worker         if (location == -1)
1885*35238bceSAndroid Build Coastguard Worker         {
1886*35238bceSAndroid Build Coastguard Worker             value.type = glu::TYPE_INVALID;
1887*35238bceSAndroid Build Coastguard Worker             valuesDst.push_back(value);
1888*35238bceSAndroid Build Coastguard Worker             if (uniform.isUsedInShader)
1889*35238bceSAndroid Build Coastguard Worker             {
1890*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "// FAILURE: " << uniform.name << " was used in shader, but has location -1"
1891*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
1892*35238bceSAndroid Build Coastguard Worker                 success = false;
1893*35238bceSAndroid Build Coastguard Worker             }
1894*35238bceSAndroid Build Coastguard Worker             continue;
1895*35238bceSAndroid Build Coastguard Worker         }
1896*35238bceSAndroid Build Coastguard Worker 
1897*35238bceSAndroid Build Coastguard Worker         value.type = uniform.type;
1898*35238bceSAndroid Build Coastguard Worker 
1899*35238bceSAndroid Build Coastguard Worker         DE_STATIC_ASSERT(sizeof(GLint) == sizeof(value.val.intV[0]));
1900*35238bceSAndroid Build Coastguard Worker         DE_STATIC_ASSERT(sizeof(GLuint) == sizeof(value.val.uintV[0]));
1901*35238bceSAndroid Build Coastguard Worker         DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(value.val.floatV[0]));
1902*35238bceSAndroid Build Coastguard Worker 
1903*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
1904*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
1905*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeIntOrIVec(uniform.type))
1906*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
1907*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeUintOrUVec(uniform.type))
1908*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glGetUniformuiv(programGL, location, &value.val.uintV[0]));
1909*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeBoolOrBVec(uniform.type))
1910*35238bceSAndroid Build Coastguard Worker         {
1911*35238bceSAndroid Build Coastguard Worker             if (m_features & FEATURE_BOOLEANAPITYPE_INT)
1912*35238bceSAndroid Build Coastguard Worker             {
1913*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
1914*35238bceSAndroid Build Coastguard Worker                 for (int i = 0; i < size; i++)
1915*35238bceSAndroid Build Coastguard Worker                     value.val.boolV[i] = value.val.intV[i] != 0;
1916*35238bceSAndroid Build Coastguard Worker             }
1917*35238bceSAndroid Build Coastguard Worker             else if (m_features & FEATURE_BOOLEANAPITYPE_UINT)
1918*35238bceSAndroid Build Coastguard Worker             {
1919*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glGetUniformuiv(programGL, location, &value.val.uintV[0]));
1920*35238bceSAndroid Build Coastguard Worker                 for (int i = 0; i < size; i++)
1921*35238bceSAndroid Build Coastguard Worker                     value.val.boolV[i] = value.val.uintV[i] != 0;
1922*35238bceSAndroid Build Coastguard Worker             }
1923*35238bceSAndroid Build Coastguard Worker             else // Default: use float.
1924*35238bceSAndroid Build Coastguard Worker             {
1925*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
1926*35238bceSAndroid Build Coastguard Worker                 for (int i = 0; i < size; i++)
1927*35238bceSAndroid Build Coastguard Worker                     value.val.boolV[i] = value.val.floatV[i] != 0.0f;
1928*35238bceSAndroid Build Coastguard Worker             }
1929*35238bceSAndroid Build Coastguard Worker         }
1930*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeSampler(uniform.type))
1931*35238bceSAndroid Build Coastguard Worker         {
1932*35238bceSAndroid Build Coastguard Worker             GLint unit = -1;
1933*35238bceSAndroid Build Coastguard Worker             GLU_CHECK_CALL(glGetUniformiv(programGL, location, &unit));
1934*35238bceSAndroid Build Coastguard Worker             value.val.samplerV.unit = unit;
1935*35238bceSAndroid Build Coastguard Worker         }
1936*35238bceSAndroid Build Coastguard Worker         else
1937*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1938*35238bceSAndroid Build Coastguard Worker 
1939*35238bceSAndroid Build Coastguard Worker         valuesDst.push_back(value);
1940*35238bceSAndroid Build Coastguard Worker 
1941*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "// Got " << uniform.name << " value " << apiVarValueStr(value)
1942*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
1943*35238bceSAndroid Build Coastguard Worker     }
1944*35238bceSAndroid Build Coastguard Worker 
1945*35238bceSAndroid Build Coastguard Worker     return success;
1946*35238bceSAndroid Build Coastguard Worker }
1947*35238bceSAndroid Build Coastguard Worker 
checkUniformDefaultValues(const vector<VarValue> & values,const vector<BasicUniform> & basicUniforms)1948*35238bceSAndroid Build Coastguard Worker bool UniformCase::checkUniformDefaultValues(const vector<VarValue> &values, const vector<BasicUniform> &basicUniforms)
1949*35238bceSAndroid Build Coastguard Worker {
1950*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1951*35238bceSAndroid Build Coastguard Worker     bool success = true;
1952*35238bceSAndroid Build Coastguard Worker 
1953*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(values.size() == basicUniforms.size());
1954*35238bceSAndroid Build Coastguard Worker 
1955*35238bceSAndroid Build Coastguard Worker     for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
1956*35238bceSAndroid Build Coastguard Worker     {
1957*35238bceSAndroid Build Coastguard Worker         const BasicUniform &uniform = basicUniforms[unifNdx];
1958*35238bceSAndroid Build Coastguard Worker         const VarValue &unifValue   = values[unifNdx];
1959*35238bceSAndroid Build Coastguard Worker         const int valSize           = glu::getDataTypeScalarSize(uniform.type);
1960*35238bceSAndroid Build Coastguard Worker 
1961*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;
1962*35238bceSAndroid Build Coastguard Worker 
1963*35238bceSAndroid Build Coastguard Worker         if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
1964*35238bceSAndroid Build Coastguard Worker             continue;
1965*35238bceSAndroid Build Coastguard Worker 
1966*35238bceSAndroid Build Coastguard Worker #define CHECK_UNIFORM(VAR_VALUE_MEMBER, ZERO)                                                                      \
1967*35238bceSAndroid Build Coastguard Worker     do                                                                                                             \
1968*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
1969*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < valSize; i++)                                                                          \
1970*35238bceSAndroid Build Coastguard Worker         {                                                                                                          \
1971*35238bceSAndroid Build Coastguard Worker             if (unifValue.val.VAR_VALUE_MEMBER[i] != (ZERO))                                                       \
1972*35238bceSAndroid Build Coastguard Worker             {                                                                                                      \
1973*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "// FAILURE: uniform " << uniform.name << " has non-zero initial value" \
1974*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;                                                                        \
1975*35238bceSAndroid Build Coastguard Worker                 success = false;                                                                                   \
1976*35238bceSAndroid Build Coastguard Worker             }                                                                                                      \
1977*35238bceSAndroid Build Coastguard Worker         }                                                                                                          \
1978*35238bceSAndroid Build Coastguard Worker     } while (false)
1979*35238bceSAndroid Build Coastguard Worker 
1980*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
1981*35238bceSAndroid Build Coastguard Worker             CHECK_UNIFORM(floatV, 0.0f);
1982*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeIntOrIVec(uniform.type))
1983*35238bceSAndroid Build Coastguard Worker             CHECK_UNIFORM(intV, 0);
1984*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeUintOrUVec(uniform.type))
1985*35238bceSAndroid Build Coastguard Worker             CHECK_UNIFORM(uintV, 0);
1986*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeBoolOrBVec(uniform.type))
1987*35238bceSAndroid Build Coastguard Worker             CHECK_UNIFORM(boolV, false);
1988*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeSampler(uniform.type))
1989*35238bceSAndroid Build Coastguard Worker         {
1990*35238bceSAndroid Build Coastguard Worker             if (unifValue.val.samplerV.unit != 0)
1991*35238bceSAndroid Build Coastguard Worker             {
1992*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "// FAILURE: uniform " << uniform.name << " has non-zero initial value"
1993*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
1994*35238bceSAndroid Build Coastguard Worker                 success = false;
1995*35238bceSAndroid Build Coastguard Worker             }
1996*35238bceSAndroid Build Coastguard Worker         }
1997*35238bceSAndroid Build Coastguard Worker         else
1998*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1999*35238bceSAndroid Build Coastguard Worker 
2000*35238bceSAndroid Build Coastguard Worker #undef CHECK_UNIFORM
2001*35238bceSAndroid Build Coastguard Worker     }
2002*35238bceSAndroid Build Coastguard Worker 
2003*35238bceSAndroid Build Coastguard Worker     return success;
2004*35238bceSAndroid Build Coastguard Worker }
2005*35238bceSAndroid Build Coastguard Worker 
assignUniforms(const vector<BasicUniform> & basicUniforms,uint32_t programGL,Random & rnd)2006*35238bceSAndroid Build Coastguard Worker void UniformCase::assignUniforms(const vector<BasicUniform> &basicUniforms, uint32_t programGL, Random &rnd)
2007*35238bceSAndroid Build Coastguard Worker {
2008*35238bceSAndroid Build Coastguard Worker     TestLog &log                    = m_testCtx.getLog();
2009*35238bceSAndroid Build Coastguard Worker     const bool transpose            = (m_features & FEATURE_MATRIXMODE_ROWMAJOR) != 0;
2010*35238bceSAndroid Build Coastguard Worker     const GLboolean transposeGL     = transpose ? GL_TRUE : GL_FALSE;
2011*35238bceSAndroid Build Coastguard Worker     const glu::DataType boolApiType = m_features & FEATURE_BOOLEANAPITYPE_INT  ? glu::TYPE_INT :
2012*35238bceSAndroid Build Coastguard Worker                                       m_features & FEATURE_BOOLEANAPITYPE_UINT ? glu::TYPE_UINT :
2013*35238bceSAndroid Build Coastguard Worker                                                                                  glu::TYPE_FLOAT;
2014*35238bceSAndroid Build Coastguard Worker 
2015*35238bceSAndroid Build Coastguard Worker     for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
2016*35238bceSAndroid Build Coastguard Worker     {
2017*35238bceSAndroid Build Coastguard Worker         const BasicUniform &uniform = basicUniforms[unifNdx];
2018*35238bceSAndroid Build Coastguard Worker         const bool isArrayMember    = uniform.elemNdx >= 0;
2019*35238bceSAndroid Build Coastguard Worker         const string queryName      = m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ?
2020*35238bceSAndroid Build Coastguard Worker                                           beforeLast(uniform.name, '[') :
2021*35238bceSAndroid Build Coastguard Worker                                           uniform.name;
2022*35238bceSAndroid Build Coastguard Worker         const int numValuesToAssign =
2023*35238bceSAndroid Build Coastguard Worker             !isArrayMember                                 ? 1 :
2024*35238bceSAndroid Build Coastguard Worker             m_features & FEATURE_ARRAYASSIGN_FULL          ? (uniform.elemNdx == 0 ? uniform.rootSize : 0) :
2025*35238bceSAndroid Build Coastguard Worker             m_features & FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO ? (uniform.elemNdx % 2 == 0 ? 2 : 0) :
2026*35238bceSAndroid Build Coastguard Worker                                                              /* Default: assign array elements separately */ 1;
2027*35238bceSAndroid Build Coastguard Worker 
2028*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numValuesToAssign >= 0);
2029*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numValuesToAssign == 1 || isArrayMember);
2030*35238bceSAndroid Build Coastguard Worker 
2031*35238bceSAndroid Build Coastguard Worker         if (numValuesToAssign == 0)
2032*35238bceSAndroid Build Coastguard Worker         {
2033*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "// Uniform " << uniform.name
2034*35238bceSAndroid Build Coastguard Worker                 << " is covered by another glUniform*v() call to the same array" << TestLog::EndMessage;
2035*35238bceSAndroid Build Coastguard Worker             continue;
2036*35238bceSAndroid Build Coastguard Worker         }
2037*35238bceSAndroid Build Coastguard Worker 
2038*35238bceSAndroid Build Coastguard Worker         const int location = glGetUniformLocation(programGL, queryName.c_str());
2039*35238bceSAndroid Build Coastguard Worker         const int typeSize = glu::getDataTypeScalarSize(uniform.type);
2040*35238bceSAndroid Build Coastguard Worker         const bool assignByValue =
2041*35238bceSAndroid Build Coastguard Worker             m_features & FEATURE_UNIFORMFUNC_VALUE && !glu::isDataTypeMatrix(uniform.type) && numValuesToAssign == 1;
2042*35238bceSAndroid Build Coastguard Worker         vector<VarValue> valuesToAssign;
2043*35238bceSAndroid Build Coastguard Worker 
2044*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < numValuesToAssign; i++)
2045*35238bceSAndroid Build Coastguard Worker         {
2046*35238bceSAndroid Build Coastguard Worker             const string curName =
2047*35238bceSAndroid Build Coastguard Worker                 isArrayMember ? beforeLast(uniform.rootName, '[') + "[" + de::toString(uniform.elemNdx + i) + "]" :
2048*35238bceSAndroid Build Coastguard Worker                                 uniform.name;
2049*35238bceSAndroid Build Coastguard Worker             VarValue unifValue;
2050*35238bceSAndroid Build Coastguard Worker 
2051*35238bceSAndroid Build Coastguard Worker             if (isArrayMember)
2052*35238bceSAndroid Build Coastguard Worker             {
2053*35238bceSAndroid Build Coastguard Worker                 const vector<BasicUniform>::const_iterator elemUnif =
2054*35238bceSAndroid Build Coastguard Worker                     BasicUniform::findWithName(basicUniforms, curName.c_str());
2055*35238bceSAndroid Build Coastguard Worker                 if (elemUnif == basicUniforms.end())
2056*35238bceSAndroid Build Coastguard Worker                     continue;
2057*35238bceSAndroid Build Coastguard Worker                 unifValue = elemUnif->finalValue;
2058*35238bceSAndroid Build Coastguard Worker             }
2059*35238bceSAndroid Build Coastguard Worker             else
2060*35238bceSAndroid Build Coastguard Worker                 unifValue = uniform.finalValue;
2061*35238bceSAndroid Build Coastguard Worker 
2062*35238bceSAndroid Build Coastguard Worker             const VarValue apiValue = glu::isDataTypeBoolOrBVec(unifValue.type) ?
2063*35238bceSAndroid Build Coastguard Worker                                           getRandomBoolRepresentation(unifValue, boolApiType, rnd) :
2064*35238bceSAndroid Build Coastguard Worker                                       glu::isDataTypeSampler(unifValue.type) ? getSamplerUnitValue(unifValue) :
2065*35238bceSAndroid Build Coastguard Worker                                                                                unifValue;
2066*35238bceSAndroid Build Coastguard Worker 
2067*35238bceSAndroid Build Coastguard Worker             valuesToAssign.push_back(glu::isDataTypeMatrix(apiValue.type) && transpose ? getTransposeMatrix(apiValue) :
2068*35238bceSAndroid Build Coastguard Worker                                                                                          apiValue);
2069*35238bceSAndroid Build Coastguard Worker 
2070*35238bceSAndroid Build Coastguard Worker             if (glu::isDataTypeBoolOrBVec(uniform.type))
2071*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "// Using type " << glu::getDataTypeName(boolApiType)
2072*35238bceSAndroid Build Coastguard Worker                     << " to set boolean value " << apiVarValueStr(unifValue) << " for " << curName
2073*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
2074*35238bceSAndroid Build Coastguard Worker             else if (glu::isDataTypeSampler(uniform.type))
2075*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "// Texture for the sampler uniform " << curName
2076*35238bceSAndroid Build Coastguard Worker                     << " will be filled with color " << apiVarValueStr(getSamplerFillValue(uniform.finalValue))
2077*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
2078*35238bceSAndroid Build Coastguard Worker         }
2079*35238bceSAndroid Build Coastguard Worker 
2080*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!valuesToAssign.empty());
2081*35238bceSAndroid Build Coastguard Worker 
2082*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeFloatOrVec(valuesToAssign[0].type))
2083*35238bceSAndroid Build Coastguard Worker         {
2084*35238bceSAndroid Build Coastguard Worker             if (assignByValue)
2085*35238bceSAndroid Build Coastguard Worker             {
2086*35238bceSAndroid Build Coastguard Worker                 const float *const ptr = &valuesToAssign[0].val.floatV[0];
2087*35238bceSAndroid Build Coastguard Worker 
2088*35238bceSAndroid Build Coastguard Worker                 switch (typeSize)
2089*35238bceSAndroid Build Coastguard Worker                 {
2090*35238bceSAndroid Build Coastguard Worker                 case 1:
2091*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform1f(location, ptr[0]));
2092*35238bceSAndroid Build Coastguard Worker                     break;
2093*35238bceSAndroid Build Coastguard Worker                 case 2:
2094*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform2f(location, ptr[0], ptr[1]));
2095*35238bceSAndroid Build Coastguard Worker                     break;
2096*35238bceSAndroid Build Coastguard Worker                 case 3:
2097*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform3f(location, ptr[0], ptr[1], ptr[2]));
2098*35238bceSAndroid Build Coastguard Worker                     break;
2099*35238bceSAndroid Build Coastguard Worker                 case 4:
2100*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform4f(location, ptr[0], ptr[1], ptr[2], ptr[3]));
2101*35238bceSAndroid Build Coastguard Worker                     break;
2102*35238bceSAndroid Build Coastguard Worker                 default:
2103*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
2104*35238bceSAndroid Build Coastguard Worker                 }
2105*35238bceSAndroid Build Coastguard Worker             }
2106*35238bceSAndroid Build Coastguard Worker             else
2107*35238bceSAndroid Build Coastguard Worker             {
2108*35238bceSAndroid Build Coastguard Worker                 vector<float> buffer(valuesToAssign.size() * typeSize);
2109*35238bceSAndroid Build Coastguard Worker                 for (int i = 0; i < (int)buffer.size(); i++)
2110*35238bceSAndroid Build Coastguard Worker                     buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];
2111*35238bceSAndroid Build Coastguard Worker 
2112*35238bceSAndroid Build Coastguard Worker                 DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0]));
2113*35238bceSAndroid Build Coastguard Worker                 switch (typeSize)
2114*35238bceSAndroid Build Coastguard Worker                 {
2115*35238bceSAndroid Build Coastguard Worker                 case 1:
2116*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform1fv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2117*35238bceSAndroid Build Coastguard Worker                     break;
2118*35238bceSAndroid Build Coastguard Worker                 case 2:
2119*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform2fv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2120*35238bceSAndroid Build Coastguard Worker                     break;
2121*35238bceSAndroid Build Coastguard Worker                 case 3:
2122*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform3fv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2123*35238bceSAndroid Build Coastguard Worker                     break;
2124*35238bceSAndroid Build Coastguard Worker                 case 4:
2125*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform4fv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2126*35238bceSAndroid Build Coastguard Worker                     break;
2127*35238bceSAndroid Build Coastguard Worker                 default:
2128*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
2129*35238bceSAndroid Build Coastguard Worker                 }
2130*35238bceSAndroid Build Coastguard Worker             }
2131*35238bceSAndroid Build Coastguard Worker         }
2132*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeMatrix(valuesToAssign[0].type))
2133*35238bceSAndroid Build Coastguard Worker         {
2134*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(!assignByValue);
2135*35238bceSAndroid Build Coastguard Worker 
2136*35238bceSAndroid Build Coastguard Worker             vector<float> buffer(valuesToAssign.size() * typeSize);
2137*35238bceSAndroid Build Coastguard Worker             for (int i = 0; i < (int)buffer.size(); i++)
2138*35238bceSAndroid Build Coastguard Worker                 buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];
2139*35238bceSAndroid Build Coastguard Worker 
2140*35238bceSAndroid Build Coastguard Worker             DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0]));
2141*35238bceSAndroid Build Coastguard Worker             switch (uniform.type)
2142*35238bceSAndroid Build Coastguard Worker             {
2143*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT_MAT2:
2144*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniformMatrix2fv(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0]));
2145*35238bceSAndroid Build Coastguard Worker                 break;
2146*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT_MAT3:
2147*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniformMatrix3fv(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0]));
2148*35238bceSAndroid Build Coastguard Worker                 break;
2149*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT_MAT4:
2150*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniformMatrix4fv(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0]));
2151*35238bceSAndroid Build Coastguard Worker                 break;
2152*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT_MAT2X3:
2153*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniformMatrix2x3fv(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0]));
2154*35238bceSAndroid Build Coastguard Worker                 break;
2155*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT_MAT2X4:
2156*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniformMatrix2x4fv(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0]));
2157*35238bceSAndroid Build Coastguard Worker                 break;
2158*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT_MAT3X2:
2159*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniformMatrix3x2fv(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0]));
2160*35238bceSAndroid Build Coastguard Worker                 break;
2161*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT_MAT3X4:
2162*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniformMatrix3x4fv(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0]));
2163*35238bceSAndroid Build Coastguard Worker                 break;
2164*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT_MAT4X2:
2165*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniformMatrix4x2fv(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0]));
2166*35238bceSAndroid Build Coastguard Worker                 break;
2167*35238bceSAndroid Build Coastguard Worker             case glu::TYPE_FLOAT_MAT4X3:
2168*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniformMatrix4x3fv(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0]));
2169*35238bceSAndroid Build Coastguard Worker                 break;
2170*35238bceSAndroid Build Coastguard Worker             default:
2171*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
2172*35238bceSAndroid Build Coastguard Worker             }
2173*35238bceSAndroid Build Coastguard Worker         }
2174*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeIntOrIVec(valuesToAssign[0].type))
2175*35238bceSAndroid Build Coastguard Worker         {
2176*35238bceSAndroid Build Coastguard Worker             if (assignByValue)
2177*35238bceSAndroid Build Coastguard Worker             {
2178*35238bceSAndroid Build Coastguard Worker                 const int32_t *const ptr = &valuesToAssign[0].val.intV[0];
2179*35238bceSAndroid Build Coastguard Worker 
2180*35238bceSAndroid Build Coastguard Worker                 switch (typeSize)
2181*35238bceSAndroid Build Coastguard Worker                 {
2182*35238bceSAndroid Build Coastguard Worker                 case 1:
2183*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform1i(location, ptr[0]));
2184*35238bceSAndroid Build Coastguard Worker                     break;
2185*35238bceSAndroid Build Coastguard Worker                 case 2:
2186*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform2i(location, ptr[0], ptr[1]));
2187*35238bceSAndroid Build Coastguard Worker                     break;
2188*35238bceSAndroid Build Coastguard Worker                 case 3:
2189*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform3i(location, ptr[0], ptr[1], ptr[2]));
2190*35238bceSAndroid Build Coastguard Worker                     break;
2191*35238bceSAndroid Build Coastguard Worker                 case 4:
2192*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform4i(location, ptr[0], ptr[1], ptr[2], ptr[3]));
2193*35238bceSAndroid Build Coastguard Worker                     break;
2194*35238bceSAndroid Build Coastguard Worker                 default:
2195*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
2196*35238bceSAndroid Build Coastguard Worker                 }
2197*35238bceSAndroid Build Coastguard Worker             }
2198*35238bceSAndroid Build Coastguard Worker             else
2199*35238bceSAndroid Build Coastguard Worker             {
2200*35238bceSAndroid Build Coastguard Worker                 vector<int32_t> buffer(valuesToAssign.size() * typeSize);
2201*35238bceSAndroid Build Coastguard Worker                 for (int i = 0; i < (int)buffer.size(); i++)
2202*35238bceSAndroid Build Coastguard Worker                     buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize];
2203*35238bceSAndroid Build Coastguard Worker 
2204*35238bceSAndroid Build Coastguard Worker                 DE_STATIC_ASSERT(sizeof(GLint) == sizeof(buffer[0]));
2205*35238bceSAndroid Build Coastguard Worker                 switch (typeSize)
2206*35238bceSAndroid Build Coastguard Worker                 {
2207*35238bceSAndroid Build Coastguard Worker                 case 1:
2208*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform1iv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2209*35238bceSAndroid Build Coastguard Worker                     break;
2210*35238bceSAndroid Build Coastguard Worker                 case 2:
2211*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform2iv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2212*35238bceSAndroid Build Coastguard Worker                     break;
2213*35238bceSAndroid Build Coastguard Worker                 case 3:
2214*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform3iv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2215*35238bceSAndroid Build Coastguard Worker                     break;
2216*35238bceSAndroid Build Coastguard Worker                 case 4:
2217*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform4iv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2218*35238bceSAndroid Build Coastguard Worker                     break;
2219*35238bceSAndroid Build Coastguard Worker                 default:
2220*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
2221*35238bceSAndroid Build Coastguard Worker                 }
2222*35238bceSAndroid Build Coastguard Worker             }
2223*35238bceSAndroid Build Coastguard Worker         }
2224*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeUintOrUVec(valuesToAssign[0].type))
2225*35238bceSAndroid Build Coastguard Worker         {
2226*35238bceSAndroid Build Coastguard Worker             if (assignByValue)
2227*35238bceSAndroid Build Coastguard Worker             {
2228*35238bceSAndroid Build Coastguard Worker                 const uint32_t *const ptr = &valuesToAssign[0].val.uintV[0];
2229*35238bceSAndroid Build Coastguard Worker 
2230*35238bceSAndroid Build Coastguard Worker                 switch (typeSize)
2231*35238bceSAndroid Build Coastguard Worker                 {
2232*35238bceSAndroid Build Coastguard Worker                 case 1:
2233*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform1ui(location, ptr[0]));
2234*35238bceSAndroid Build Coastguard Worker                     break;
2235*35238bceSAndroid Build Coastguard Worker                 case 2:
2236*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform2ui(location, ptr[0], ptr[1]));
2237*35238bceSAndroid Build Coastguard Worker                     break;
2238*35238bceSAndroid Build Coastguard Worker                 case 3:
2239*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform3ui(location, ptr[0], ptr[1], ptr[2]));
2240*35238bceSAndroid Build Coastguard Worker                     break;
2241*35238bceSAndroid Build Coastguard Worker                 case 4:
2242*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform4ui(location, ptr[0], ptr[1], ptr[2], ptr[3]));
2243*35238bceSAndroid Build Coastguard Worker                     break;
2244*35238bceSAndroid Build Coastguard Worker                 default:
2245*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
2246*35238bceSAndroid Build Coastguard Worker                 }
2247*35238bceSAndroid Build Coastguard Worker             }
2248*35238bceSAndroid Build Coastguard Worker             else
2249*35238bceSAndroid Build Coastguard Worker             {
2250*35238bceSAndroid Build Coastguard Worker                 vector<uint32_t> buffer(valuesToAssign.size() * typeSize);
2251*35238bceSAndroid Build Coastguard Worker                 for (int i = 0; i < (int)buffer.size(); i++)
2252*35238bceSAndroid Build Coastguard Worker                     buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize];
2253*35238bceSAndroid Build Coastguard Worker 
2254*35238bceSAndroid Build Coastguard Worker                 DE_STATIC_ASSERT(sizeof(GLuint) == sizeof(buffer[0]));
2255*35238bceSAndroid Build Coastguard Worker                 switch (typeSize)
2256*35238bceSAndroid Build Coastguard Worker                 {
2257*35238bceSAndroid Build Coastguard Worker                 case 1:
2258*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform1uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2259*35238bceSAndroid Build Coastguard Worker                     break;
2260*35238bceSAndroid Build Coastguard Worker                 case 2:
2261*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform2uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2262*35238bceSAndroid Build Coastguard Worker                     break;
2263*35238bceSAndroid Build Coastguard Worker                 case 3:
2264*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform3uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2265*35238bceSAndroid Build Coastguard Worker                     break;
2266*35238bceSAndroid Build Coastguard Worker                 case 4:
2267*35238bceSAndroid Build Coastguard Worker                     GLU_CHECK_CALL(glUniform4uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0]));
2268*35238bceSAndroid Build Coastguard Worker                     break;
2269*35238bceSAndroid Build Coastguard Worker                 default:
2270*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
2271*35238bceSAndroid Build Coastguard Worker                 }
2272*35238bceSAndroid Build Coastguard Worker             }
2273*35238bceSAndroid Build Coastguard Worker         }
2274*35238bceSAndroid Build Coastguard Worker         else if (glu::isDataTypeSampler(valuesToAssign[0].type))
2275*35238bceSAndroid Build Coastguard Worker         {
2276*35238bceSAndroid Build Coastguard Worker             if (assignByValue)
2277*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniform1i(location, uniform.finalValue.val.samplerV.unit));
2278*35238bceSAndroid Build Coastguard Worker             else
2279*35238bceSAndroid Build Coastguard Worker             {
2280*35238bceSAndroid Build Coastguard Worker                 const GLint unit = uniform.finalValue.val.samplerV.unit;
2281*35238bceSAndroid Build Coastguard Worker                 GLU_CHECK_CALL(glUniform1iv(location, (GLsizei)valuesToAssign.size(), &unit));
2282*35238bceSAndroid Build Coastguard Worker             }
2283*35238bceSAndroid Build Coastguard Worker         }
2284*35238bceSAndroid Build Coastguard Worker         else
2285*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
2286*35238bceSAndroid Build Coastguard Worker     }
2287*35238bceSAndroid Build Coastguard Worker }
2288*35238bceSAndroid Build Coastguard Worker 
compareUniformValues(const vector<VarValue> & values,const vector<BasicUniform> & basicUniforms)2289*35238bceSAndroid Build Coastguard Worker bool UniformCase::compareUniformValues(const vector<VarValue> &values, const vector<BasicUniform> &basicUniforms)
2290*35238bceSAndroid Build Coastguard Worker {
2291*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
2292*35238bceSAndroid Build Coastguard Worker     bool success = true;
2293*35238bceSAndroid Build Coastguard Worker 
2294*35238bceSAndroid Build Coastguard Worker     for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
2295*35238bceSAndroid Build Coastguard Worker     {
2296*35238bceSAndroid Build Coastguard Worker         const BasicUniform &uniform = basicUniforms[unifNdx];
2297*35238bceSAndroid Build Coastguard Worker         const VarValue &unifValue   = values[unifNdx];
2298*35238bceSAndroid Build Coastguard Worker 
2299*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;
2300*35238bceSAndroid Build Coastguard Worker 
2301*35238bceSAndroid Build Coastguard Worker         if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
2302*35238bceSAndroid Build Coastguard Worker             continue;
2303*35238bceSAndroid Build Coastguard Worker 
2304*35238bceSAndroid Build Coastguard Worker         if (!apiVarValueEquals(unifValue, uniform.finalValue))
2305*35238bceSAndroid Build Coastguard Worker         {
2306*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "// FAILURE: value obtained with glGetUniform*() for uniform " << uniform.name
2307*35238bceSAndroid Build Coastguard Worker                 << " differs from value set with glUniform*()" << TestLog::EndMessage;
2308*35238bceSAndroid Build Coastguard Worker             success = false;
2309*35238bceSAndroid Build Coastguard Worker         }
2310*35238bceSAndroid Build Coastguard Worker     }
2311*35238bceSAndroid Build Coastguard Worker 
2312*35238bceSAndroid Build Coastguard Worker     return success;
2313*35238bceSAndroid Build Coastguard Worker }
2314*35238bceSAndroid Build Coastguard Worker 
renderTest(const vector<BasicUniform> & basicUniforms,const ShaderProgram & program,Random & rnd)2315*35238bceSAndroid Build Coastguard Worker bool UniformCase::renderTest(const vector<BasicUniform> &basicUniforms, const ShaderProgram &program, Random &rnd)
2316*35238bceSAndroid Build Coastguard Worker {
2317*35238bceSAndroid Build Coastguard Worker     TestLog &log                          = m_testCtx.getLog();
2318*35238bceSAndroid Build Coastguard Worker     const tcu::RenderTarget &renderTarget = m_context.getRenderTarget();
2319*35238bceSAndroid Build Coastguard Worker     const int viewportW                   = de::min(renderTarget.getWidth(), MAX_RENDER_WIDTH);
2320*35238bceSAndroid Build Coastguard Worker     const int viewportH                   = de::min(renderTarget.getHeight(), MAX_RENDER_HEIGHT);
2321*35238bceSAndroid Build Coastguard Worker     const int viewportX                   = rnd.getInt(0, renderTarget.getWidth() - viewportW);
2322*35238bceSAndroid Build Coastguard Worker     const int viewportY                   = rnd.getInt(0, renderTarget.getHeight() - viewportH);
2323*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedImg(viewportW, viewportH);
2324*35238bceSAndroid Build Coastguard Worker 
2325*35238bceSAndroid Build Coastguard Worker     // Assert that no two samplers of different types have the same texture unit - this is an error in GL.
2326*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)basicUniforms.size(); i++)
2327*35238bceSAndroid Build Coastguard Worker     {
2328*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeSampler(basicUniforms[i].type))
2329*35238bceSAndroid Build Coastguard Worker         {
2330*35238bceSAndroid Build Coastguard Worker             for (int j = 0; j < i; j++)
2331*35238bceSAndroid Build Coastguard Worker             {
2332*35238bceSAndroid Build Coastguard Worker                 if (glu::isDataTypeSampler(basicUniforms[j].type) && basicUniforms[i].type != basicUniforms[j].type)
2333*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(basicUniforms[i].finalValue.val.samplerV.unit !=
2334*35238bceSAndroid Build Coastguard Worker                               basicUniforms[j].finalValue.val.samplerV.unit);
2335*35238bceSAndroid Build Coastguard Worker             }
2336*35238bceSAndroid Build Coastguard Worker         }
2337*35238bceSAndroid Build Coastguard Worker     }
2338*35238bceSAndroid Build Coastguard Worker 
2339*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)basicUniforms.size(); i++)
2340*35238bceSAndroid Build Coastguard Worker     {
2341*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeSampler(basicUniforms[i].type) &&
2342*35238bceSAndroid Build Coastguard Worker             std::find(m_filledTextureUnits.begin(), m_filledTextureUnits.end(),
2343*35238bceSAndroid Build Coastguard Worker                       basicUniforms[i].finalValue.val.samplerV.unit) == m_filledTextureUnits.end())
2344*35238bceSAndroid Build Coastguard Worker         {
2345*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "// Filling texture at unit " << apiVarValueStr(basicUniforms[i].finalValue)
2346*35238bceSAndroid Build Coastguard Worker                 << " with color " << shaderVarValueStr(basicUniforms[i].finalValue) << TestLog::EndMessage;
2347*35238bceSAndroid Build Coastguard Worker             setupTexture(basicUniforms[i].finalValue);
2348*35238bceSAndroid Build Coastguard Worker         }
2349*35238bceSAndroid Build Coastguard Worker     }
2350*35238bceSAndroid Build Coastguard Worker 
2351*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportW, viewportH));
2352*35238bceSAndroid Build Coastguard Worker 
2353*35238bceSAndroid Build Coastguard Worker     {
2354*35238bceSAndroid Build Coastguard Worker         static const float position[]   = {-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f,
2355*35238bceSAndroid Build Coastguard Worker                                            +1.0f, -1.0f, 0.0f, 1.0f, +1.0f, +1.0f, 0.0f, 1.0f};
2356*35238bceSAndroid Build Coastguard Worker         static const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
2357*35238bceSAndroid Build Coastguard Worker 
2358*35238bceSAndroid Build Coastguard Worker         const int posLoc = glGetAttribLocation(program.getProgram(), "a_position");
2359*35238bceSAndroid Build Coastguard Worker         glEnableVertexAttribArray(posLoc);
2360*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]);
2361*35238bceSAndroid Build Coastguard Worker         GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_SHORT, &indices[0]));
2362*35238bceSAndroid Build Coastguard Worker     }
2363*35238bceSAndroid Build Coastguard Worker 
2364*35238bceSAndroid Build Coastguard Worker     glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess());
2365*35238bceSAndroid Build Coastguard Worker 
2366*35238bceSAndroid Build Coastguard Worker     int numFailedPixels = 0;
2367*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < renderedImg.getHeight(); y++)
2368*35238bceSAndroid Build Coastguard Worker     {
2369*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < renderedImg.getWidth(); x++)
2370*35238bceSAndroid Build Coastguard Worker         {
2371*35238bceSAndroid Build Coastguard Worker             if (renderedImg.getPixel(x, y) != tcu::RGBA::white())
2372*35238bceSAndroid Build Coastguard Worker                 numFailedPixels += 1;
2373*35238bceSAndroid Build Coastguard Worker         }
2374*35238bceSAndroid Build Coastguard Worker     }
2375*35238bceSAndroid Build Coastguard Worker 
2376*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
2377*35238bceSAndroid Build Coastguard Worker     {
2378*35238bceSAndroid Build Coastguard Worker         log << TestLog::Image("RenderedImage", "Rendered image", renderedImg);
2379*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "FAILURE: image comparison failed, got " << numFailedPixels << " non-white pixels"
2380*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
2381*35238bceSAndroid Build Coastguard Worker         return false;
2382*35238bceSAndroid Build Coastguard Worker     }
2383*35238bceSAndroid Build Coastguard Worker     else
2384*35238bceSAndroid Build Coastguard Worker     {
2385*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Success: got all-white pixels (all uniforms have correct values)"
2386*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
2387*35238bceSAndroid Build Coastguard Worker         return true;
2388*35238bceSAndroid Build Coastguard Worker     }
2389*35238bceSAndroid Build Coastguard Worker }
2390*35238bceSAndroid Build Coastguard Worker 
iterate(void)2391*35238bceSAndroid Build Coastguard Worker UniformCase::IterateResult UniformCase::iterate(void)
2392*35238bceSAndroid Build Coastguard Worker {
2393*35238bceSAndroid Build Coastguard Worker     Random rnd(deStringHash(getName()) ^ (uint32_t)m_context.getTestContext().getCommandLine().getBaseSeed());
2394*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
2395*35238bceSAndroid Build Coastguard Worker     vector<BasicUniform> basicUniforms;
2396*35238bceSAndroid Build Coastguard Worker     vector<BasicUniformReportRef> basicUniformReportsRef;
2397*35238bceSAndroid Build Coastguard Worker 
2398*35238bceSAndroid Build Coastguard Worker     {
2399*35238bceSAndroid Build Coastguard Worker         int samplerUnitCounter = 0;
2400*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
2401*35238bceSAndroid Build Coastguard Worker             generateBasicUniforms(basicUniforms, basicUniformReportsRef, m_uniformCollection->getUniform(i).type,
2402*35238bceSAndroid Build Coastguard Worker                                   m_uniformCollection->getUniform(i).name.c_str(), true, samplerUnitCounter, rnd);
2403*35238bceSAndroid Build Coastguard Worker     }
2404*35238bceSAndroid Build Coastguard Worker 
2405*35238bceSAndroid Build Coastguard Worker     const string vertexSource   = generateVertexSource(basicUniforms);
2406*35238bceSAndroid Build Coastguard Worker     const string fragmentSource = generateFragmentSource(basicUniforms);
2407*35238bceSAndroid Build Coastguard Worker     const ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexSource, fragmentSource));
2408*35238bceSAndroid Build Coastguard Worker 
2409*35238bceSAndroid Build Coastguard Worker     log << program;
2410*35238bceSAndroid Build Coastguard Worker 
2411*35238bceSAndroid Build Coastguard Worker     if (!program.isOk())
2412*35238bceSAndroid Build Coastguard Worker     {
2413*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
2414*35238bceSAndroid Build Coastguard Worker         return STOP;
2415*35238bceSAndroid Build Coastguard Worker     }
2416*35238bceSAndroid Build Coastguard Worker 
2417*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glUseProgram(program.getProgram()));
2418*35238bceSAndroid Build Coastguard Worker 
2419*35238bceSAndroid Build Coastguard Worker     const bool success = test(basicUniforms, basicUniformReportsRef, program, rnd);
2420*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Passed" : "Failed");
2421*35238bceSAndroid Build Coastguard Worker 
2422*35238bceSAndroid Build Coastguard Worker     return STOP;
2423*35238bceSAndroid Build Coastguard Worker }
2424*35238bceSAndroid Build Coastguard Worker 
2425*35238bceSAndroid Build Coastguard Worker class UniformInfoQueryCase : public UniformCase
2426*35238bceSAndroid Build Coastguard Worker {
2427*35238bceSAndroid Build Coastguard Worker public:
2428*35238bceSAndroid Build Coastguard Worker     enum CaseType
2429*35238bceSAndroid Build Coastguard Worker     {
2430*35238bceSAndroid Build Coastguard Worker         CASETYPE_UNIFORM = 0,        //!< Check info returned by glGetActiveUniform().
2431*35238bceSAndroid Build Coastguard Worker         CASETYPE_INDICES_UNIFORMSIV, //!< Check info returned by glGetUniformIndices() + glGetActiveUniformsiv().
2432*35238bceSAndroid Build Coastguard Worker         CASETYPE_CONSISTENCY,        //!< Query info with both above methods, and check consistency.
2433*35238bceSAndroid Build Coastguard Worker 
2434*35238bceSAndroid Build Coastguard Worker         CASETYPE_LAST
2435*35238bceSAndroid Build Coastguard Worker     };
2436*35238bceSAndroid Build Coastguard Worker 
2437*35238bceSAndroid Build Coastguard Worker     UniformInfoQueryCase(Context &context, const char *name, const char *description, CaseShaderType shaderType,
2438*35238bceSAndroid Build Coastguard Worker                          const SharedPtr<const UniformCollection> &uniformCollection, CaseType caseType,
2439*35238bceSAndroid Build Coastguard Worker                          uint32_t additionalFeatures = 0);
2440*35238bceSAndroid Build Coastguard Worker     bool test(const vector<BasicUniform> &basicUniforms, const vector<BasicUniformReportRef> &basicUniformReportsRef,
2441*35238bceSAndroid Build Coastguard Worker               const ShaderProgram &program, Random &rnd);
2442*35238bceSAndroid Build Coastguard Worker 
2443*35238bceSAndroid Build Coastguard Worker     static const char *getCaseTypeName(CaseType caseType);
2444*35238bceSAndroid Build Coastguard Worker     static const char *getCaseTypeDescription(CaseType caseType);
2445*35238bceSAndroid Build Coastguard Worker 
2446*35238bceSAndroid Build Coastguard Worker private:
2447*35238bceSAndroid Build Coastguard Worker     const CaseType m_caseType;
2448*35238bceSAndroid Build Coastguard Worker };
2449*35238bceSAndroid Build Coastguard Worker 
getCaseTypeName(const CaseType caseType)2450*35238bceSAndroid Build Coastguard Worker const char *UniformInfoQueryCase::getCaseTypeName(const CaseType caseType)
2451*35238bceSAndroid Build Coastguard Worker {
2452*35238bceSAndroid Build Coastguard Worker     switch (caseType)
2453*35238bceSAndroid Build Coastguard Worker     {
2454*35238bceSAndroid Build Coastguard Worker     case CASETYPE_UNIFORM:
2455*35238bceSAndroid Build Coastguard Worker         return "active_uniform";
2456*35238bceSAndroid Build Coastguard Worker     case CASETYPE_INDICES_UNIFORMSIV:
2457*35238bceSAndroid Build Coastguard Worker         return "indices_active_uniformsiv";
2458*35238bceSAndroid Build Coastguard Worker     case CASETYPE_CONSISTENCY:
2459*35238bceSAndroid Build Coastguard Worker         return "consistency";
2460*35238bceSAndroid Build Coastguard Worker     default:
2461*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2462*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
2463*35238bceSAndroid Build Coastguard Worker     }
2464*35238bceSAndroid Build Coastguard Worker }
2465*35238bceSAndroid Build Coastguard Worker 
getCaseTypeDescription(const CaseType caseType)2466*35238bceSAndroid Build Coastguard Worker const char *UniformInfoQueryCase::getCaseTypeDescription(const CaseType caseType)
2467*35238bceSAndroid Build Coastguard Worker {
2468*35238bceSAndroid Build Coastguard Worker     switch (caseType)
2469*35238bceSAndroid Build Coastguard Worker     {
2470*35238bceSAndroid Build Coastguard Worker     case CASETYPE_UNIFORM:
2471*35238bceSAndroid Build Coastguard Worker         return "Test glGetActiveUniform()";
2472*35238bceSAndroid Build Coastguard Worker     case CASETYPE_INDICES_UNIFORMSIV:
2473*35238bceSAndroid Build Coastguard Worker         return "Test glGetUniformIndices() along with glGetActiveUniformsiv()";
2474*35238bceSAndroid Build Coastguard Worker     case CASETYPE_CONSISTENCY:
2475*35238bceSAndroid Build Coastguard Worker         return "Check consistency between results from glGetActiveUniform() and glGetUniformIndices() + "
2476*35238bceSAndroid Build Coastguard Worker                "glGetActiveUniformsiv()";
2477*35238bceSAndroid Build Coastguard Worker     default:
2478*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2479*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
2480*35238bceSAndroid Build Coastguard Worker     }
2481*35238bceSAndroid Build Coastguard Worker }
2482*35238bceSAndroid Build Coastguard Worker 
UniformInfoQueryCase(Context & context,const char * const name,const char * const description,const CaseShaderType shaderType,const SharedPtr<const UniformCollection> & uniformCollection,const CaseType caseType,const uint32_t additionalFeatures)2483*35238bceSAndroid Build Coastguard Worker UniformInfoQueryCase::UniformInfoQueryCase(Context &context, const char *const name, const char *const description,
2484*35238bceSAndroid Build Coastguard Worker                                            const CaseShaderType shaderType,
2485*35238bceSAndroid Build Coastguard Worker                                            const SharedPtr<const UniformCollection> &uniformCollection,
2486*35238bceSAndroid Build Coastguard Worker                                            const CaseType caseType, const uint32_t additionalFeatures)
2487*35238bceSAndroid Build Coastguard Worker     : UniformCase(context, name, description, shaderType, uniformCollection, additionalFeatures)
2488*35238bceSAndroid Build Coastguard Worker     , m_caseType(caseType)
2489*35238bceSAndroid Build Coastguard Worker {
2490*35238bceSAndroid Build Coastguard Worker }
2491*35238bceSAndroid Build Coastguard Worker 
test(const vector<BasicUniform> & basicUniforms,const vector<BasicUniformReportRef> & basicUniformReportsRef,const ShaderProgram & program,Random & rnd)2492*35238bceSAndroid Build Coastguard Worker bool UniformInfoQueryCase::test(const vector<BasicUniform> &basicUniforms,
2493*35238bceSAndroid Build Coastguard Worker                                 const vector<BasicUniformReportRef> &basicUniformReportsRef,
2494*35238bceSAndroid Build Coastguard Worker                                 const ShaderProgram &program, Random &rnd)
2495*35238bceSAndroid Build Coastguard Worker {
2496*35238bceSAndroid Build Coastguard Worker     DE_UNREF(basicUniforms);
2497*35238bceSAndroid Build Coastguard Worker     DE_UNREF(rnd);
2498*35238bceSAndroid Build Coastguard Worker 
2499*35238bceSAndroid Build Coastguard Worker     const uint32_t programGL = program.getProgram();
2500*35238bceSAndroid Build Coastguard Worker     TestLog &log             = m_testCtx.getLog();
2501*35238bceSAndroid Build Coastguard Worker     vector<BasicUniformReportGL> basicUniformReportsUniform;
2502*35238bceSAndroid Build Coastguard Worker     vector<BasicUniformReportGL> basicUniformReportsUniformsiv;
2503*35238bceSAndroid Build Coastguard Worker 
2504*35238bceSAndroid Build Coastguard Worker     if (m_caseType == CASETYPE_UNIFORM || m_caseType == CASETYPE_CONSISTENCY)
2505*35238bceSAndroid Build Coastguard Worker     {
2506*35238bceSAndroid Build Coastguard Worker         bool success = false;
2507*35238bceSAndroid Build Coastguard Worker 
2508*35238bceSAndroid Build Coastguard Worker         {
2509*35238bceSAndroid Build Coastguard Worker             const ScopedLogSection section(log, "InfoGetActiveUniform",
2510*35238bceSAndroid Build Coastguard Worker                                            "Uniform information queries with glGetActiveUniform()");
2511*35238bceSAndroid Build Coastguard Worker             success = getActiveUniforms(basicUniformReportsUniform, basicUniformReportsRef, programGL);
2512*35238bceSAndroid Build Coastguard Worker         }
2513*35238bceSAndroid Build Coastguard Worker 
2514*35238bceSAndroid Build Coastguard Worker         if (!success)
2515*35238bceSAndroid Build Coastguard Worker         {
2516*35238bceSAndroid Build Coastguard Worker             if (m_caseType == CASETYPE_UNIFORM)
2517*35238bceSAndroid Build Coastguard Worker                 return false;
2518*35238bceSAndroid Build Coastguard Worker             else
2519*35238bceSAndroid Build Coastguard Worker             {
2520*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(m_caseType == CASETYPE_CONSISTENCY);
2521*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "// Note: this is a consistency case, so ignoring above failure(s)"
2522*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
2523*35238bceSAndroid Build Coastguard Worker             }
2524*35238bceSAndroid Build Coastguard Worker         }
2525*35238bceSAndroid Build Coastguard Worker     }
2526*35238bceSAndroid Build Coastguard Worker 
2527*35238bceSAndroid Build Coastguard Worker     if (m_caseType == CASETYPE_INDICES_UNIFORMSIV || m_caseType == CASETYPE_CONSISTENCY)
2528*35238bceSAndroid Build Coastguard Worker     {
2529*35238bceSAndroid Build Coastguard Worker         bool success = false;
2530*35238bceSAndroid Build Coastguard Worker 
2531*35238bceSAndroid Build Coastguard Worker         {
2532*35238bceSAndroid Build Coastguard Worker             const ScopedLogSection section(
2533*35238bceSAndroid Build Coastguard Worker                 log, "InfoGetActiveUniformsiv",
2534*35238bceSAndroid Build Coastguard Worker                 "Uniform information queries with glGetUniformIndices() and glGetActiveUniformsiv()");
2535*35238bceSAndroid Build Coastguard Worker             success = getActiveUniformsiv(basicUniformReportsUniformsiv, basicUniformReportsRef, programGL);
2536*35238bceSAndroid Build Coastguard Worker         }
2537*35238bceSAndroid Build Coastguard Worker 
2538*35238bceSAndroid Build Coastguard Worker         if (!success)
2539*35238bceSAndroid Build Coastguard Worker         {
2540*35238bceSAndroid Build Coastguard Worker             if (m_caseType == CASETYPE_INDICES_UNIFORMSIV)
2541*35238bceSAndroid Build Coastguard Worker                 return false;
2542*35238bceSAndroid Build Coastguard Worker             else
2543*35238bceSAndroid Build Coastguard Worker             {
2544*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(m_caseType == CASETYPE_CONSISTENCY);
2545*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "// Note: this is a consistency case, so ignoring above failure(s)"
2546*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
2547*35238bceSAndroid Build Coastguard Worker             }
2548*35238bceSAndroid Build Coastguard Worker         }
2549*35238bceSAndroid Build Coastguard Worker     }
2550*35238bceSAndroid Build Coastguard Worker 
2551*35238bceSAndroid Build Coastguard Worker     if (m_caseType == CASETYPE_CONSISTENCY)
2552*35238bceSAndroid Build Coastguard Worker     {
2553*35238bceSAndroid Build Coastguard Worker         bool success = false;
2554*35238bceSAndroid Build Coastguard Worker 
2555*35238bceSAndroid Build Coastguard Worker         {
2556*35238bceSAndroid Build Coastguard Worker             const ScopedLogSection section(
2557*35238bceSAndroid Build Coastguard Worker                 log, "CompareUniformVsUniformsiv",
2558*35238bceSAndroid Build Coastguard Worker                 "Comparison of results from glGetActiveUniform() and glGetActiveUniformsiv()");
2559*35238bceSAndroid Build Coastguard Worker             success = uniformVsUniformsivComparison(basicUniformReportsUniform, basicUniformReportsUniformsiv);
2560*35238bceSAndroid Build Coastguard Worker         }
2561*35238bceSAndroid Build Coastguard Worker 
2562*35238bceSAndroid Build Coastguard Worker         if (!success)
2563*35238bceSAndroid Build Coastguard Worker             return false;
2564*35238bceSAndroid Build Coastguard Worker     }
2565*35238bceSAndroid Build Coastguard Worker 
2566*35238bceSAndroid Build Coastguard Worker     return true;
2567*35238bceSAndroid Build Coastguard Worker }
2568*35238bceSAndroid Build Coastguard Worker 
2569*35238bceSAndroid Build Coastguard Worker class UniformValueCase : public UniformCase
2570*35238bceSAndroid Build Coastguard Worker {
2571*35238bceSAndroid Build Coastguard Worker public:
2572*35238bceSAndroid Build Coastguard Worker     enum ValueToCheck
2573*35238bceSAndroid Build Coastguard Worker     {
2574*35238bceSAndroid Build Coastguard Worker         VALUETOCHECK_INITIAL = 0, //!< Verify the initial values of the uniforms (i.e. check that they're zero).
2575*35238bceSAndroid Build Coastguard Worker         VALUETOCHECK_ASSIGNED,    //!< Assign values to uniforms with glUniform*(), and check those.
2576*35238bceSAndroid Build Coastguard Worker 
2577*35238bceSAndroid Build Coastguard Worker         VALUETOCHECK_LAST
2578*35238bceSAndroid Build Coastguard Worker     };
2579*35238bceSAndroid Build Coastguard Worker     enum CheckMethod
2580*35238bceSAndroid Build Coastguard Worker     {
2581*35238bceSAndroid Build Coastguard Worker         CHECKMETHOD_GET_UNIFORM = 0, //!< Check values with glGetUniform*().
2582*35238bceSAndroid Build Coastguard Worker         CHECKMETHOD_RENDER,          //!< Check values by rendering with the value-checking shader.
2583*35238bceSAndroid Build Coastguard Worker 
2584*35238bceSAndroid Build Coastguard Worker         CHECKMETHOD_LAST
2585*35238bceSAndroid Build Coastguard Worker     };
2586*35238bceSAndroid Build Coastguard Worker     enum AssignMethod
2587*35238bceSAndroid Build Coastguard Worker     {
2588*35238bceSAndroid Build Coastguard Worker         ASSIGNMETHOD_POINTER = 0,
2589*35238bceSAndroid Build Coastguard Worker         ASSIGNMETHOD_VALUE,
2590*35238bceSAndroid Build Coastguard Worker 
2591*35238bceSAndroid Build Coastguard Worker         ASSIGNMETHOD_LAST
2592*35238bceSAndroid Build Coastguard Worker     };
2593*35238bceSAndroid Build Coastguard Worker 
2594*35238bceSAndroid Build Coastguard Worker     UniformValueCase(Context &context, const char *name, const char *description, CaseShaderType shaderType,
2595*35238bceSAndroid Build Coastguard Worker                      const SharedPtr<const UniformCollection> &uniformCollection, ValueToCheck valueToCheck,
2596*35238bceSAndroid Build Coastguard Worker                      CheckMethod checkMethod, AssignMethod assignMethod, uint32_t additionalFeatures = 0);
2597*35238bceSAndroid Build Coastguard Worker 
2598*35238bceSAndroid Build Coastguard Worker     bool test(const vector<BasicUniform> &basicUniforms, const vector<BasicUniformReportRef> &basicUniformReportsRef,
2599*35238bceSAndroid Build Coastguard Worker               const ShaderProgram &program, Random &rnd);
2600*35238bceSAndroid Build Coastguard Worker 
2601*35238bceSAndroid Build Coastguard Worker     static const char *getValueToCheckName(ValueToCheck valueToCheck);
2602*35238bceSAndroid Build Coastguard Worker     static const char *getValueToCheckDescription(ValueToCheck valueToCheck);
2603*35238bceSAndroid Build Coastguard Worker     static const char *getCheckMethodName(CheckMethod checkMethod);
2604*35238bceSAndroid Build Coastguard Worker     static const char *getCheckMethodDescription(CheckMethod checkMethod);
2605*35238bceSAndroid Build Coastguard Worker     static const char *getAssignMethodName(AssignMethod checkMethod);
2606*35238bceSAndroid Build Coastguard Worker     static const char *getAssignMethodDescription(AssignMethod checkMethod);
2607*35238bceSAndroid Build Coastguard Worker 
2608*35238bceSAndroid Build Coastguard Worker private:
2609*35238bceSAndroid Build Coastguard Worker     const ValueToCheck m_valueToCheck;
2610*35238bceSAndroid Build Coastguard Worker     const CheckMethod m_checkMethod;
2611*35238bceSAndroid Build Coastguard Worker };
2612*35238bceSAndroid Build Coastguard Worker 
getValueToCheckName(const ValueToCheck valueToCheck)2613*35238bceSAndroid Build Coastguard Worker const char *UniformValueCase::getValueToCheckName(const ValueToCheck valueToCheck)
2614*35238bceSAndroid Build Coastguard Worker {
2615*35238bceSAndroid Build Coastguard Worker     switch (valueToCheck)
2616*35238bceSAndroid Build Coastguard Worker     {
2617*35238bceSAndroid Build Coastguard Worker     case VALUETOCHECK_INITIAL:
2618*35238bceSAndroid Build Coastguard Worker         return "initial";
2619*35238bceSAndroid Build Coastguard Worker     case VALUETOCHECK_ASSIGNED:
2620*35238bceSAndroid Build Coastguard Worker         return "assigned";
2621*35238bceSAndroid Build Coastguard Worker     default:
2622*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2623*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
2624*35238bceSAndroid Build Coastguard Worker     }
2625*35238bceSAndroid Build Coastguard Worker }
2626*35238bceSAndroid Build Coastguard Worker 
getValueToCheckDescription(const ValueToCheck valueToCheck)2627*35238bceSAndroid Build Coastguard Worker const char *UniformValueCase::getValueToCheckDescription(const ValueToCheck valueToCheck)
2628*35238bceSAndroid Build Coastguard Worker {
2629*35238bceSAndroid Build Coastguard Worker     switch (valueToCheck)
2630*35238bceSAndroid Build Coastguard Worker     {
2631*35238bceSAndroid Build Coastguard Worker     case VALUETOCHECK_INITIAL:
2632*35238bceSAndroid Build Coastguard Worker         return "Check initial uniform values (zeros)";
2633*35238bceSAndroid Build Coastguard Worker     case VALUETOCHECK_ASSIGNED:
2634*35238bceSAndroid Build Coastguard Worker         return "Check assigned uniform values";
2635*35238bceSAndroid Build Coastguard Worker     default:
2636*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2637*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
2638*35238bceSAndroid Build Coastguard Worker     }
2639*35238bceSAndroid Build Coastguard Worker }
2640*35238bceSAndroid Build Coastguard Worker 
getCheckMethodName(const CheckMethod checkMethod)2641*35238bceSAndroid Build Coastguard Worker const char *UniformValueCase::getCheckMethodName(const CheckMethod checkMethod)
2642*35238bceSAndroid Build Coastguard Worker {
2643*35238bceSAndroid Build Coastguard Worker     switch (checkMethod)
2644*35238bceSAndroid Build Coastguard Worker     {
2645*35238bceSAndroid Build Coastguard Worker     case CHECKMETHOD_GET_UNIFORM:
2646*35238bceSAndroid Build Coastguard Worker         return "get_uniform";
2647*35238bceSAndroid Build Coastguard Worker     case CHECKMETHOD_RENDER:
2648*35238bceSAndroid Build Coastguard Worker         return "render";
2649*35238bceSAndroid Build Coastguard Worker     default:
2650*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2651*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
2652*35238bceSAndroid Build Coastguard Worker     }
2653*35238bceSAndroid Build Coastguard Worker }
2654*35238bceSAndroid Build Coastguard Worker 
getCheckMethodDescription(const CheckMethod checkMethod)2655*35238bceSAndroid Build Coastguard Worker const char *UniformValueCase::getCheckMethodDescription(const CheckMethod checkMethod)
2656*35238bceSAndroid Build Coastguard Worker {
2657*35238bceSAndroid Build Coastguard Worker     switch (checkMethod)
2658*35238bceSAndroid Build Coastguard Worker     {
2659*35238bceSAndroid Build Coastguard Worker     case CHECKMETHOD_GET_UNIFORM:
2660*35238bceSAndroid Build Coastguard Worker         return "Verify values with glGetUniform*()";
2661*35238bceSAndroid Build Coastguard Worker     case CHECKMETHOD_RENDER:
2662*35238bceSAndroid Build Coastguard Worker         return "Verify values by rendering";
2663*35238bceSAndroid Build Coastguard Worker     default:
2664*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2665*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
2666*35238bceSAndroid Build Coastguard Worker     }
2667*35238bceSAndroid Build Coastguard Worker }
2668*35238bceSAndroid Build Coastguard Worker 
getAssignMethodName(const AssignMethod assignMethod)2669*35238bceSAndroid Build Coastguard Worker const char *UniformValueCase::getAssignMethodName(const AssignMethod assignMethod)
2670*35238bceSAndroid Build Coastguard Worker {
2671*35238bceSAndroid Build Coastguard Worker     switch (assignMethod)
2672*35238bceSAndroid Build Coastguard Worker     {
2673*35238bceSAndroid Build Coastguard Worker     case ASSIGNMETHOD_POINTER:
2674*35238bceSAndroid Build Coastguard Worker         return "by_pointer";
2675*35238bceSAndroid Build Coastguard Worker     case ASSIGNMETHOD_VALUE:
2676*35238bceSAndroid Build Coastguard Worker         return "by_value";
2677*35238bceSAndroid Build Coastguard Worker     default:
2678*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2679*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
2680*35238bceSAndroid Build Coastguard Worker     }
2681*35238bceSAndroid Build Coastguard Worker }
2682*35238bceSAndroid Build Coastguard Worker 
getAssignMethodDescription(const AssignMethod assignMethod)2683*35238bceSAndroid Build Coastguard Worker const char *UniformValueCase::getAssignMethodDescription(const AssignMethod assignMethod)
2684*35238bceSAndroid Build Coastguard Worker {
2685*35238bceSAndroid Build Coastguard Worker     switch (assignMethod)
2686*35238bceSAndroid Build Coastguard Worker     {
2687*35238bceSAndroid Build Coastguard Worker     case ASSIGNMETHOD_POINTER:
2688*35238bceSAndroid Build Coastguard Worker         return "Assign values by-pointer";
2689*35238bceSAndroid Build Coastguard Worker     case ASSIGNMETHOD_VALUE:
2690*35238bceSAndroid Build Coastguard Worker         return "Assign values by-value";
2691*35238bceSAndroid Build Coastguard Worker     default:
2692*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2693*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
2694*35238bceSAndroid Build Coastguard Worker     }
2695*35238bceSAndroid Build Coastguard Worker }
2696*35238bceSAndroid Build Coastguard Worker 
UniformValueCase(Context & context,const char * const name,const char * const description,const CaseShaderType shaderType,const SharedPtr<const UniformCollection> & uniformCollection,const ValueToCheck valueToCheck,const CheckMethod checkMethod,const AssignMethod assignMethod,const uint32_t additionalFeatures)2697*35238bceSAndroid Build Coastguard Worker UniformValueCase::UniformValueCase(Context &context, const char *const name, const char *const description,
2698*35238bceSAndroid Build Coastguard Worker                                    const CaseShaderType shaderType,
2699*35238bceSAndroid Build Coastguard Worker                                    const SharedPtr<const UniformCollection> &uniformCollection,
2700*35238bceSAndroid Build Coastguard Worker                                    const ValueToCheck valueToCheck, const CheckMethod checkMethod,
2701*35238bceSAndroid Build Coastguard Worker                                    const AssignMethod assignMethod, const uint32_t additionalFeatures)
2702*35238bceSAndroid Build Coastguard Worker     : UniformCase(context, name, description, shaderType, uniformCollection,
2703*35238bceSAndroid Build Coastguard Worker                   (valueToCheck == VALUETOCHECK_INITIAL ? FEATURE_UNIFORMVALUE_ZERO : 0) |
2704*35238bceSAndroid Build Coastguard Worker                       (assignMethod == ASSIGNMETHOD_VALUE ? FEATURE_UNIFORMFUNC_VALUE : 0) | additionalFeatures)
2705*35238bceSAndroid Build Coastguard Worker     , m_valueToCheck(valueToCheck)
2706*35238bceSAndroid Build Coastguard Worker     , m_checkMethod(checkMethod)
2707*35238bceSAndroid Build Coastguard Worker {
2708*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!(assignMethod == ASSIGNMETHOD_LAST && valueToCheck == VALUETOCHECK_ASSIGNED));
2709*35238bceSAndroid Build Coastguard Worker }
2710*35238bceSAndroid Build Coastguard Worker 
test(const vector<BasicUniform> & basicUniforms,const vector<BasicUniformReportRef> & basicUniformReportsRef,const ShaderProgram & program,Random & rnd)2711*35238bceSAndroid Build Coastguard Worker bool UniformValueCase::test(const vector<BasicUniform> &basicUniforms,
2712*35238bceSAndroid Build Coastguard Worker                             const vector<BasicUniformReportRef> &basicUniformReportsRef, const ShaderProgram &program,
2713*35238bceSAndroid Build Coastguard Worker                             Random &rnd)
2714*35238bceSAndroid Build Coastguard Worker {
2715*35238bceSAndroid Build Coastguard Worker     DE_UNREF(basicUniformReportsRef);
2716*35238bceSAndroid Build Coastguard Worker 
2717*35238bceSAndroid Build Coastguard Worker     const uint32_t programGL = program.getProgram();
2718*35238bceSAndroid Build Coastguard Worker     TestLog &log             = m_testCtx.getLog();
2719*35238bceSAndroid Build Coastguard Worker 
2720*35238bceSAndroid Build Coastguard Worker     if (m_valueToCheck == VALUETOCHECK_ASSIGNED)
2721*35238bceSAndroid Build Coastguard Worker     {
2722*35238bceSAndroid Build Coastguard Worker         const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
2723*35238bceSAndroid Build Coastguard Worker         assignUniforms(basicUniforms, programGL, rnd);
2724*35238bceSAndroid Build Coastguard Worker     }
2725*35238bceSAndroid Build Coastguard Worker     else
2726*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_valueToCheck == VALUETOCHECK_INITIAL);
2727*35238bceSAndroid Build Coastguard Worker 
2728*35238bceSAndroid Build Coastguard Worker     if (m_checkMethod == CHECKMETHOD_GET_UNIFORM)
2729*35238bceSAndroid Build Coastguard Worker     {
2730*35238bceSAndroid Build Coastguard Worker         vector<VarValue> values;
2731*35238bceSAndroid Build Coastguard Worker 
2732*35238bceSAndroid Build Coastguard Worker         {
2733*35238bceSAndroid Build Coastguard Worker             const ScopedLogSection section(log, "GetUniforms", "Uniform value query");
2734*35238bceSAndroid Build Coastguard Worker             const bool success = getUniforms(values, basicUniforms, program.getProgram());
2735*35238bceSAndroid Build Coastguard Worker 
2736*35238bceSAndroid Build Coastguard Worker             if (!success)
2737*35238bceSAndroid Build Coastguard Worker                 return false;
2738*35238bceSAndroid Build Coastguard Worker         }
2739*35238bceSAndroid Build Coastguard Worker 
2740*35238bceSAndroid Build Coastguard Worker         if (m_valueToCheck == VALUETOCHECK_ASSIGNED)
2741*35238bceSAndroid Build Coastguard Worker         {
2742*35238bceSAndroid Build Coastguard Worker             const ScopedLogSection section(log, "ValueCheck",
2743*35238bceSAndroid Build Coastguard Worker                                            "Verify that the reported values match the assigned values");
2744*35238bceSAndroid Build Coastguard Worker             const bool success = compareUniformValues(values, basicUniforms);
2745*35238bceSAndroid Build Coastguard Worker 
2746*35238bceSAndroid Build Coastguard Worker             if (!success)
2747*35238bceSAndroid Build Coastguard Worker                 return false;
2748*35238bceSAndroid Build Coastguard Worker         }
2749*35238bceSAndroid Build Coastguard Worker         else
2750*35238bceSAndroid Build Coastguard Worker         {
2751*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(m_valueToCheck == VALUETOCHECK_INITIAL);
2752*35238bceSAndroid Build Coastguard Worker 
2753*35238bceSAndroid Build Coastguard Worker             const ScopedLogSection section(log, "ValueCheck",
2754*35238bceSAndroid Build Coastguard Worker                                            "Verify that the uniforms have correct initial values (zeros)");
2755*35238bceSAndroid Build Coastguard Worker             const bool success = checkUniformDefaultValues(values, basicUniforms);
2756*35238bceSAndroid Build Coastguard Worker 
2757*35238bceSAndroid Build Coastguard Worker             if (!success)
2758*35238bceSAndroid Build Coastguard Worker                 return false;
2759*35238bceSAndroid Build Coastguard Worker         }
2760*35238bceSAndroid Build Coastguard Worker     }
2761*35238bceSAndroid Build Coastguard Worker     else
2762*35238bceSAndroid Build Coastguard Worker     {
2763*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_checkMethod == CHECKMETHOD_RENDER);
2764*35238bceSAndroid Build Coastguard Worker 
2765*35238bceSAndroid Build Coastguard Worker         const ScopedLogSection section(log, "RenderTest", "Render test");
2766*35238bceSAndroid Build Coastguard Worker         const bool success = renderTest(basicUniforms, program, rnd);
2767*35238bceSAndroid Build Coastguard Worker 
2768*35238bceSAndroid Build Coastguard Worker         if (!success)
2769*35238bceSAndroid Build Coastguard Worker             return false;
2770*35238bceSAndroid Build Coastguard Worker     }
2771*35238bceSAndroid Build Coastguard Worker 
2772*35238bceSAndroid Build Coastguard Worker     return true;
2773*35238bceSAndroid Build Coastguard Worker }
2774*35238bceSAndroid Build Coastguard Worker 
2775*35238bceSAndroid Build Coastguard Worker class RandomUniformCase : public UniformCase
2776*35238bceSAndroid Build Coastguard Worker {
2777*35238bceSAndroid Build Coastguard Worker public:
2778*35238bceSAndroid Build Coastguard Worker     RandomUniformCase(Context &m_context, const char *name, const char *description, uint32_t seed);
2779*35238bceSAndroid Build Coastguard Worker 
2780*35238bceSAndroid Build Coastguard Worker     bool test(const vector<BasicUniform> &basicUniforms, const vector<BasicUniformReportRef> &basicUniformReportsRef,
2781*35238bceSAndroid Build Coastguard Worker               const ShaderProgram &program, Random &rnd);
2782*35238bceSAndroid Build Coastguard Worker };
2783*35238bceSAndroid Build Coastguard Worker 
RandomUniformCase(Context & context,const char * const name,const char * const description,const uint32_t seed)2784*35238bceSAndroid Build Coastguard Worker RandomUniformCase::RandomUniformCase(Context &context, const char *const name, const char *const description,
2785*35238bceSAndroid Build Coastguard Worker                                      const uint32_t seed)
2786*35238bceSAndroid Build Coastguard Worker     : UniformCase(context, name, description, seed ^ (uint32_t)context.getTestContext().getCommandLine().getBaseSeed())
2787*35238bceSAndroid Build Coastguard Worker {
2788*35238bceSAndroid Build Coastguard Worker }
2789*35238bceSAndroid Build Coastguard Worker 
test(const vector<BasicUniform> & basicUniforms,const vector<BasicUniformReportRef> & basicUniformReportsRef,const ShaderProgram & program,Random & rnd)2790*35238bceSAndroid Build Coastguard Worker bool RandomUniformCase::test(const vector<BasicUniform> &basicUniforms,
2791*35238bceSAndroid Build Coastguard Worker                              const vector<BasicUniformReportRef> &basicUniformReportsRef, const ShaderProgram &program,
2792*35238bceSAndroid Build Coastguard Worker                              Random &rnd)
2793*35238bceSAndroid Build Coastguard Worker {
2794*35238bceSAndroid Build Coastguard Worker     // \note Different sampler types may not be bound to same unit when rendering.
2795*35238bceSAndroid Build Coastguard Worker     const bool renderingPossible =
2796*35238bceSAndroid Build Coastguard Worker         (m_features & FEATURE_UNIFORMVALUE_ZERO) == 0 || !m_uniformCollection->containsSeveralSamplerTypes();
2797*35238bceSAndroid Build Coastguard Worker 
2798*35238bceSAndroid Build Coastguard Worker     bool performGetActiveUniforms         = rnd.getBool();
2799*35238bceSAndroid Build Coastguard Worker     const bool performGetActiveUniformsiv = rnd.getBool();
2800*35238bceSAndroid Build Coastguard Worker     const bool performUniformVsUniformsivComparison =
2801*35238bceSAndroid Build Coastguard Worker         performGetActiveUniforms && performGetActiveUniformsiv && rnd.getBool();
2802*35238bceSAndroid Build Coastguard Worker     const bool performGetUniforms               = rnd.getBool();
2803*35238bceSAndroid Build Coastguard Worker     const bool performCheckUniformDefaultValues = performGetUniforms && rnd.getBool();
2804*35238bceSAndroid Build Coastguard Worker     const bool performAssignUniforms            = rnd.getBool();
2805*35238bceSAndroid Build Coastguard Worker     const bool performCompareUniformValues      = performGetUniforms && performAssignUniforms && rnd.getBool();
2806*35238bceSAndroid Build Coastguard Worker     const bool performRenderTest                = renderingPossible && performAssignUniforms && rnd.getBool();
2807*35238bceSAndroid Build Coastguard Worker     const uint32_t programGL                    = program.getProgram();
2808*35238bceSAndroid Build Coastguard Worker     TestLog &log                                = m_testCtx.getLog();
2809*35238bceSAndroid Build Coastguard Worker 
2810*35238bceSAndroid Build Coastguard Worker     if (!(performGetActiveUniforms || performGetActiveUniformsiv || performUniformVsUniformsivComparison ||
2811*35238bceSAndroid Build Coastguard Worker           performGetUniforms || performCheckUniformDefaultValues || performAssignUniforms ||
2812*35238bceSAndroid Build Coastguard Worker           performCompareUniformValues || performRenderTest))
2813*35238bceSAndroid Build Coastguard Worker         performGetActiveUniforms = true; // Do something at least.
2814*35238bceSAndroid Build Coastguard Worker 
2815*35238bceSAndroid Build Coastguard Worker #define PERFORM_AND_CHECK(CALL, SECTION_NAME, SECTION_DESCRIPTION)                  \
2816*35238bceSAndroid Build Coastguard Worker     do                                                                              \
2817*35238bceSAndroid Build Coastguard Worker     {                                                                               \
2818*35238bceSAndroid Build Coastguard Worker         const ScopedLogSection section(log, (SECTION_NAME), (SECTION_DESCRIPTION)); \
2819*35238bceSAndroid Build Coastguard Worker         const bool success = (CALL);                                                \
2820*35238bceSAndroid Build Coastguard Worker         if (!success)                                                               \
2821*35238bceSAndroid Build Coastguard Worker             return false;                                                           \
2822*35238bceSAndroid Build Coastguard Worker     } while (false)
2823*35238bceSAndroid Build Coastguard Worker 
2824*35238bceSAndroid Build Coastguard Worker     {
2825*35238bceSAndroid Build Coastguard Worker         vector<BasicUniformReportGL> reportsUniform;
2826*35238bceSAndroid Build Coastguard Worker         vector<BasicUniformReportGL> reportsUniformsiv;
2827*35238bceSAndroid Build Coastguard Worker 
2828*35238bceSAndroid Build Coastguard Worker         if (performGetActiveUniforms)
2829*35238bceSAndroid Build Coastguard Worker             PERFORM_AND_CHECK(getActiveUniforms(reportsUniform, basicUniformReportsRef, programGL),
2830*35238bceSAndroid Build Coastguard Worker                               "InfoGetActiveUniform", "Uniform information queries with glGetActiveUniform()");
2831*35238bceSAndroid Build Coastguard Worker         if (performGetActiveUniformsiv)
2832*35238bceSAndroid Build Coastguard Worker             PERFORM_AND_CHECK(getActiveUniformsiv(reportsUniformsiv, basicUniformReportsRef, programGL),
2833*35238bceSAndroid Build Coastguard Worker                               "InfoGetActiveUniformsiv",
2834*35238bceSAndroid Build Coastguard Worker                               "Uniform information queries with glGetIndices() and glGetActiveUniformsiv()");
2835*35238bceSAndroid Build Coastguard Worker         if (performUniformVsUniformsivComparison)
2836*35238bceSAndroid Build Coastguard Worker             PERFORM_AND_CHECK(uniformVsUniformsivComparison(reportsUniform, reportsUniformsiv),
2837*35238bceSAndroid Build Coastguard Worker                               "CompareUniformVsUniformsiv",
2838*35238bceSAndroid Build Coastguard Worker                               "Comparison of results from glGetActiveUniform() and glGetActiveUniformsiv()");
2839*35238bceSAndroid Build Coastguard Worker     }
2840*35238bceSAndroid Build Coastguard Worker 
2841*35238bceSAndroid Build Coastguard Worker     {
2842*35238bceSAndroid Build Coastguard Worker         vector<VarValue> uniformDefaultValues;
2843*35238bceSAndroid Build Coastguard Worker 
2844*35238bceSAndroid Build Coastguard Worker         if (performGetUniforms)
2845*35238bceSAndroid Build Coastguard Worker             PERFORM_AND_CHECK(getUniforms(uniformDefaultValues, basicUniforms, programGL), "GetUniformDefaults",
2846*35238bceSAndroid Build Coastguard Worker                               "Uniform default value query");
2847*35238bceSAndroid Build Coastguard Worker         if (performCheckUniformDefaultValues)
2848*35238bceSAndroid Build Coastguard Worker             PERFORM_AND_CHECK(checkUniformDefaultValues(uniformDefaultValues, basicUniforms), "DefaultValueCheck",
2849*35238bceSAndroid Build Coastguard Worker                               "Verify that the uniforms have correct initial values (zeros)");
2850*35238bceSAndroid Build Coastguard Worker     }
2851*35238bceSAndroid Build Coastguard Worker 
2852*35238bceSAndroid Build Coastguard Worker     {
2853*35238bceSAndroid Build Coastguard Worker         vector<VarValue> uniformValues;
2854*35238bceSAndroid Build Coastguard Worker 
2855*35238bceSAndroid Build Coastguard Worker         if (performAssignUniforms)
2856*35238bceSAndroid Build Coastguard Worker         {
2857*35238bceSAndroid Build Coastguard Worker             const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
2858*35238bceSAndroid Build Coastguard Worker             assignUniforms(basicUniforms, programGL, rnd);
2859*35238bceSAndroid Build Coastguard Worker         }
2860*35238bceSAndroid Build Coastguard Worker         if (performCompareUniformValues)
2861*35238bceSAndroid Build Coastguard Worker         {
2862*35238bceSAndroid Build Coastguard Worker             PERFORM_AND_CHECK(getUniforms(uniformValues, basicUniforms, programGL), "GetUniforms",
2863*35238bceSAndroid Build Coastguard Worker                               "Uniform value query");
2864*35238bceSAndroid Build Coastguard Worker             PERFORM_AND_CHECK(compareUniformValues(uniformValues, basicUniforms), "ValueCheck",
2865*35238bceSAndroid Build Coastguard Worker                               "Verify that the reported values match the assigned values");
2866*35238bceSAndroid Build Coastguard Worker         }
2867*35238bceSAndroid Build Coastguard Worker     }
2868*35238bceSAndroid Build Coastguard Worker 
2869*35238bceSAndroid Build Coastguard Worker     if (performRenderTest)
2870*35238bceSAndroid Build Coastguard Worker         PERFORM_AND_CHECK(renderTest(basicUniforms, program, rnd), "RenderTest", "Render test");
2871*35238bceSAndroid Build Coastguard Worker 
2872*35238bceSAndroid Build Coastguard Worker #undef PERFORM_AND_CHECK
2873*35238bceSAndroid Build Coastguard Worker 
2874*35238bceSAndroid Build Coastguard Worker     return true;
2875*35238bceSAndroid Build Coastguard Worker }
2876*35238bceSAndroid Build Coastguard Worker 
UniformApiTests(Context & context)2877*35238bceSAndroid Build Coastguard Worker UniformApiTests::UniformApiTests(Context &context) : TestCaseGroup(context, "uniform_api", "Uniform API Tests")
2878*35238bceSAndroid Build Coastguard Worker {
2879*35238bceSAndroid Build Coastguard Worker }
2880*35238bceSAndroid Build Coastguard Worker 
~UniformApiTests(void)2881*35238bceSAndroid Build Coastguard Worker UniformApiTests::~UniformApiTests(void)
2882*35238bceSAndroid Build Coastguard Worker {
2883*35238bceSAndroid Build Coastguard Worker }
2884*35238bceSAndroid Build Coastguard Worker 
2885*35238bceSAndroid Build Coastguard Worker namespace
2886*35238bceSAndroid Build Coastguard Worker {
2887*35238bceSAndroid Build Coastguard Worker 
2888*35238bceSAndroid Build Coastguard Worker // \note Although this is only used in UniformApiTest::init, it needs to be defined here as it's used as a template argument.
2889*35238bceSAndroid Build Coastguard Worker struct UniformCollectionCase
2890*35238bceSAndroid Build Coastguard Worker {
2891*35238bceSAndroid Build Coastguard Worker     string namePrefix;
2892*35238bceSAndroid Build Coastguard Worker     SharedPtr<const UniformCollection> uniformCollection;
2893*35238bceSAndroid Build Coastguard Worker 
UniformCollectionCasedeqp::gles3::Functional::__anondef265660611::UniformCollectionCase2894*35238bceSAndroid Build Coastguard Worker     UniformCollectionCase(const char *const name, const UniformCollection *uniformCollection_)
2895*35238bceSAndroid Build Coastguard Worker         : namePrefix(name ? name + string("_") : "")
2896*35238bceSAndroid Build Coastguard Worker         , uniformCollection(uniformCollection_)
2897*35238bceSAndroid Build Coastguard Worker     {
2898*35238bceSAndroid Build Coastguard Worker     }
2899*35238bceSAndroid Build Coastguard Worker };
2900*35238bceSAndroid Build Coastguard Worker 
2901*35238bceSAndroid Build Coastguard Worker } // namespace
2902*35238bceSAndroid Build Coastguard Worker 
init(void)2903*35238bceSAndroid Build Coastguard Worker void UniformApiTests::init(void)
2904*35238bceSAndroid Build Coastguard Worker {
2905*35238bceSAndroid Build Coastguard Worker     // Generate sets of UniformCollections that are used by several cases.
2906*35238bceSAndroid Build Coastguard Worker 
2907*35238bceSAndroid Build Coastguard Worker     enum
2908*35238bceSAndroid Build Coastguard Worker     {
2909*35238bceSAndroid Build Coastguard Worker         UNIFORMCOLLECTIONS_BASIC = 0,
2910*35238bceSAndroid Build Coastguard Worker         UNIFORMCOLLECTIONS_BASIC_ARRAY,
2911*35238bceSAndroid Build Coastguard Worker         UNIFORMCOLLECTIONS_BASIC_STRUCT,
2912*35238bceSAndroid Build Coastguard Worker         UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY,
2913*35238bceSAndroid Build Coastguard Worker         UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT,
2914*35238bceSAndroid Build Coastguard Worker         UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS,
2915*35238bceSAndroid Build Coastguard Worker         UNIFORMCOLLECTIONS_MULTIPLE_BASIC,
2916*35238bceSAndroid Build Coastguard Worker         UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY,
2917*35238bceSAndroid Build Coastguard Worker         UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS,
2918*35238bceSAndroid Build Coastguard Worker 
2919*35238bceSAndroid Build Coastguard Worker         UNIFORMCOLLECTIONS_LAST
2920*35238bceSAndroid Build Coastguard Worker     };
2921*35238bceSAndroid Build Coastguard Worker 
2922*35238bceSAndroid Build Coastguard Worker     struct UniformCollectionGroup
2923*35238bceSAndroid Build Coastguard Worker     {
2924*35238bceSAndroid Build Coastguard Worker         string name;
2925*35238bceSAndroid Build Coastguard Worker         vector<UniformCollectionCase> cases;
2926*35238bceSAndroid Build Coastguard Worker     } defaultUniformCollections[UNIFORMCOLLECTIONS_LAST];
2927*35238bceSAndroid Build Coastguard Worker 
2928*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].name                 = "basic";
2929*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].name           = "basic_array";
2930*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].name          = "basic_struct";
2931*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].name       = "struct_in_array";
2932*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].name       = "array_in_struct";
2933*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].name = "nested_structs_arrays";
2934*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].name        = "multiple_basic";
2935*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].name  = "multiple_basic_array";
2936*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].name =
2937*35238bceSAndroid Build Coastguard Worker         "multiple_nested_structs_arrays";
2938*35238bceSAndroid Build Coastguard Worker 
2939*35238bceSAndroid Build Coastguard Worker     for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_testDataTypes); dataTypeNdx++)
2940*35238bceSAndroid Build Coastguard Worker     {
2941*35238bceSAndroid Build Coastguard Worker         const glu::DataType dataType = s_testDataTypes[dataTypeNdx];
2942*35238bceSAndroid Build Coastguard Worker         const char *const typeName   = glu::getDataTypeName(dataType);
2943*35238bceSAndroid Build Coastguard Worker 
2944*35238bceSAndroid Build Coastguard Worker         defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].cases.push_back(
2945*35238bceSAndroid Build Coastguard Worker             UniformCollectionCase(typeName, UniformCollection::basic(dataType)));
2946*35238bceSAndroid Build Coastguard Worker 
2947*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeScalar(dataType) ||
2948*35238bceSAndroid Build Coastguard Worker             (glu::isDataTypeVector(dataType) && glu::getDataTypeScalarSize(dataType) == 4) ||
2949*35238bceSAndroid Build Coastguard Worker             dataType == glu::TYPE_FLOAT_MAT4 || dataType == glu::TYPE_SAMPLER_2D)
2950*35238bceSAndroid Build Coastguard Worker             defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].cases.push_back(
2951*35238bceSAndroid Build Coastguard Worker                 UniformCollectionCase(typeName, UniformCollection::basicArray(dataType)));
2952*35238bceSAndroid Build Coastguard Worker 
2953*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeScalar(dataType) || dataType == glu::TYPE_FLOAT_MAT4 || dataType == glu::TYPE_SAMPLER_2D)
2954*35238bceSAndroid Build Coastguard Worker         {
2955*35238bceSAndroid Build Coastguard Worker             const glu::DataType secondDataType = glu::isDataTypeScalar(dataType) ? glu::getDataTypeVector(dataType, 4) :
2956*35238bceSAndroid Build Coastguard Worker                                                  dataType == glu::TYPE_FLOAT_MAT4 ? glu::TYPE_FLOAT_MAT2 :
2957*35238bceSAndroid Build Coastguard Worker                                                  dataType == glu::TYPE_SAMPLER_2D ? glu::TYPE_SAMPLER_CUBE :
2958*35238bceSAndroid Build Coastguard Worker                                                                                     glu::TYPE_LAST;
2959*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(secondDataType != glu::TYPE_LAST);
2960*35238bceSAndroid Build Coastguard Worker             const char *const secondTypeName = glu::getDataTypeName(secondDataType);
2961*35238bceSAndroid Build Coastguard Worker             const string name                = string("") + typeName + "_" + secondTypeName;
2962*35238bceSAndroid Build Coastguard Worker 
2963*35238bceSAndroid Build Coastguard Worker             defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].cases.push_back(
2964*35238bceSAndroid Build Coastguard Worker                 UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, false)));
2965*35238bceSAndroid Build Coastguard Worker             defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].cases.push_back(
2966*35238bceSAndroid Build Coastguard Worker                 UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, true)));
2967*35238bceSAndroid Build Coastguard Worker             defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].cases.push_back(
2968*35238bceSAndroid Build Coastguard Worker                 UniformCollectionCase(name.c_str(), UniformCollection::structInArray(dataType, secondDataType, false)));
2969*35238bceSAndroid Build Coastguard Worker             defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].cases.push_back(
2970*35238bceSAndroid Build Coastguard Worker                 UniformCollectionCase(name.c_str(), UniformCollection::nestedArraysStructs(dataType, secondDataType)));
2971*35238bceSAndroid Build Coastguard Worker         }
2972*35238bceSAndroid Build Coastguard Worker     }
2973*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].cases.push_back(
2974*35238bceSAndroid Build Coastguard Worker         UniformCollectionCase(DE_NULL, UniformCollection::multipleBasic()));
2975*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].cases.push_back(
2976*35238bceSAndroid Build Coastguard Worker         UniformCollectionCase(DE_NULL, UniformCollection::multipleBasicArray()));
2977*35238bceSAndroid Build Coastguard Worker     defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].cases.push_back(
2978*35238bceSAndroid Build Coastguard Worker         UniformCollectionCase(DE_NULL, UniformCollection::multipleNestedArraysStructs()));
2979*35238bceSAndroid Build Coastguard Worker 
2980*35238bceSAndroid Build Coastguard Worker     // Info-query cases (check info returned by e.g. glGetActiveUniforms()).
2981*35238bceSAndroid Build Coastguard Worker 
2982*35238bceSAndroid Build Coastguard Worker     {
2983*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const infoQueryGroup =
2984*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(m_context, "info_query", "Test uniform info querying functions");
2985*35238bceSAndroid Build Coastguard Worker         addChild(infoQueryGroup);
2986*35238bceSAndroid Build Coastguard Worker         for (int caseTypeI = 0; caseTypeI < (int)UniformInfoQueryCase::CASETYPE_LAST; caseTypeI++)
2987*35238bceSAndroid Build Coastguard Worker         {
2988*35238bceSAndroid Build Coastguard Worker             const UniformInfoQueryCase::CaseType caseType = (UniformInfoQueryCase::CaseType)caseTypeI;
2989*35238bceSAndroid Build Coastguard Worker             TestCaseGroup *const caseTypeGroup =
2990*35238bceSAndroid Build Coastguard Worker                 new TestCaseGroup(m_context, UniformInfoQueryCase::getCaseTypeName(caseType),
2991*35238bceSAndroid Build Coastguard Worker                                   UniformInfoQueryCase::getCaseTypeDescription(caseType));
2992*35238bceSAndroid Build Coastguard Worker             infoQueryGroup->addChild(caseTypeGroup);
2993*35238bceSAndroid Build Coastguard Worker 
2994*35238bceSAndroid Build Coastguard Worker             for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
2995*35238bceSAndroid Build Coastguard Worker             {
2996*35238bceSAndroid Build Coastguard Worker                 const int numArrayFirstElemNameCases = caseType == UniformInfoQueryCase::CASETYPE_INDICES_UNIFORMSIV &&
2997*35238bceSAndroid Build Coastguard Worker                                                                collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY ?
2998*35238bceSAndroid Build Coastguard Worker                                                            2 :
2999*35238bceSAndroid Build Coastguard Worker                                                            1;
3000*35238bceSAndroid Build Coastguard Worker 
3001*35238bceSAndroid Build Coastguard Worker                 for (int referToFirstArrayElemWithoutIndexI = 0;
3002*35238bceSAndroid Build Coastguard Worker                      referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases;
3003*35238bceSAndroid Build Coastguard Worker                      referToFirstArrayElemWithoutIndexI++)
3004*35238bceSAndroid Build Coastguard Worker                 {
3005*35238bceSAndroid Build Coastguard Worker                     const UniformCollectionGroup &collectionGroup = defaultUniformCollections[collectionGroupNdx];
3006*35238bceSAndroid Build Coastguard Worker                     const string collectionGroupName =
3007*35238bceSAndroid Build Coastguard Worker                         collectionGroup.name +
3008*35238bceSAndroid Build Coastguard Worker                         (referToFirstArrayElemWithoutIndexI == 0 ? "" : "_first_elem_without_brackets");
3009*35238bceSAndroid Build Coastguard Worker                     TestCaseGroup *const collectionTestGroup =
3010*35238bceSAndroid Build Coastguard Worker                         new TestCaseGroup(m_context, collectionGroupName.c_str(), "");
3011*35238bceSAndroid Build Coastguard Worker                     caseTypeGroup->addChild(collectionTestGroup);
3012*35238bceSAndroid Build Coastguard Worker 
3013*35238bceSAndroid Build Coastguard Worker                     for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
3014*35238bceSAndroid Build Coastguard Worker                     {
3015*35238bceSAndroid Build Coastguard Worker                         const UniformCollectionCase &collectionCase = collectionGroup.cases[collectionNdx];
3016*35238bceSAndroid Build Coastguard Worker 
3017*35238bceSAndroid Build Coastguard Worker                         for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
3018*35238bceSAndroid Build Coastguard Worker                         {
3019*35238bceSAndroid Build Coastguard Worker                             const string name =
3020*35238bceSAndroid Build Coastguard Worker                                 collectionCase.namePrefix + getCaseShaderTypeName((CaseShaderType)shaderType);
3021*35238bceSAndroid Build Coastguard Worker                             const SharedPtr<const UniformCollection> &uniformCollection =
3022*35238bceSAndroid Build Coastguard Worker                                 collectionCase.uniformCollection;
3023*35238bceSAndroid Build Coastguard Worker 
3024*35238bceSAndroid Build Coastguard Worker                             collectionTestGroup->addChild(
3025*35238bceSAndroid Build Coastguard Worker                                 new UniformInfoQueryCase(m_context, name.c_str(), "", (CaseShaderType)shaderType,
3026*35238bceSAndroid Build Coastguard Worker                                                          uniformCollection, (UniformInfoQueryCase::CaseType)caseType,
3027*35238bceSAndroid Build Coastguard Worker                                                          referToFirstArrayElemWithoutIndexI == 0 ?
3028*35238bceSAndroid Build Coastguard Worker                                                              0 :
3029*35238bceSAndroid Build Coastguard Worker                                                              UniformCase::FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX));
3030*35238bceSAndroid Build Coastguard Worker                         }
3031*35238bceSAndroid Build Coastguard Worker                     }
3032*35238bceSAndroid Build Coastguard Worker                 }
3033*35238bceSAndroid Build Coastguard Worker             }
3034*35238bceSAndroid Build Coastguard Worker 
3035*35238bceSAndroid Build Coastguard Worker             // Info-querying cases when unused uniforms are present.
3036*35238bceSAndroid Build Coastguard Worker 
3037*35238bceSAndroid Build Coastguard Worker             {
3038*35238bceSAndroid Build Coastguard Worker                 TestCaseGroup *const unusedUniformsGroup =
3039*35238bceSAndroid Build Coastguard Worker                     new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
3040*35238bceSAndroid Build Coastguard Worker                 caseTypeGroup->addChild(unusedUniformsGroup);
3041*35238bceSAndroid Build Coastguard Worker 
3042*35238bceSAndroid Build Coastguard Worker                 const UniformCollectionGroup &collectionGroup =
3043*35238bceSAndroid Build Coastguard Worker                     defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];
3044*35238bceSAndroid Build Coastguard Worker 
3045*35238bceSAndroid Build Coastguard Worker                 for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
3046*35238bceSAndroid Build Coastguard Worker                 {
3047*35238bceSAndroid Build Coastguard Worker                     const UniformCollectionCase &collectionCase                 = collectionGroup.cases[collectionNdx];
3048*35238bceSAndroid Build Coastguard Worker                     const string collName                                       = collectionCase.namePrefix;
3049*35238bceSAndroid Build Coastguard Worker                     const SharedPtr<const UniformCollection> &uniformCollection = collectionCase.uniformCollection;
3050*35238bceSAndroid Build Coastguard Worker 
3051*35238bceSAndroid Build Coastguard Worker                     for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
3052*35238bceSAndroid Build Coastguard Worker                     {
3053*35238bceSAndroid Build Coastguard Worker                         const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
3054*35238bceSAndroid Build Coastguard Worker                         unusedUniformsGroup->addChild(
3055*35238bceSAndroid Build Coastguard Worker                             new UniformInfoQueryCase(m_context, name.c_str(), "", (CaseShaderType)shaderType,
3056*35238bceSAndroid Build Coastguard Worker                                                      uniformCollection, (UniformInfoQueryCase::CaseType)caseType,
3057*35238bceSAndroid Build Coastguard Worker                                                      UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER |
3058*35238bceSAndroid Build Coastguard Worker                                                          UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX));
3059*35238bceSAndroid Build Coastguard Worker                     }
3060*35238bceSAndroid Build Coastguard Worker                 }
3061*35238bceSAndroid Build Coastguard Worker             }
3062*35238bceSAndroid Build Coastguard Worker         }
3063*35238bceSAndroid Build Coastguard Worker     }
3064*35238bceSAndroid Build Coastguard Worker 
3065*35238bceSAndroid Build Coastguard Worker     // Cases testing uniform values.
3066*35238bceSAndroid Build Coastguard Worker 
3067*35238bceSAndroid Build Coastguard Worker     {
3068*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const valueGroup = new TestCaseGroup(m_context, "value", "Uniform value tests");
3069*35238bceSAndroid Build Coastguard Worker         addChild(valueGroup);
3070*35238bceSAndroid Build Coastguard Worker 
3071*35238bceSAndroid Build Coastguard Worker         // Cases checking uniforms' initial values (all must be zeros), with glGetUniform*() or by rendering.
3072*35238bceSAndroid Build Coastguard Worker 
3073*35238bceSAndroid Build Coastguard Worker         {
3074*35238bceSAndroid Build Coastguard Worker             TestCaseGroup *const initialValuesGroup = new TestCaseGroup(
3075*35238bceSAndroid Build Coastguard Worker                 m_context, UniformValueCase::getValueToCheckName(UniformValueCase::VALUETOCHECK_INITIAL),
3076*35238bceSAndroid Build Coastguard Worker                 UniformValueCase::getValueToCheckDescription(UniformValueCase::VALUETOCHECK_INITIAL));
3077*35238bceSAndroid Build Coastguard Worker             valueGroup->addChild(initialValuesGroup);
3078*35238bceSAndroid Build Coastguard Worker 
3079*35238bceSAndroid Build Coastguard Worker             for (int checkMethodI = 0; checkMethodI < (int)UniformValueCase::CHECKMETHOD_LAST; checkMethodI++)
3080*35238bceSAndroid Build Coastguard Worker             {
3081*35238bceSAndroid Build Coastguard Worker                 const UniformValueCase::CheckMethod checkMethod = (UniformValueCase::CheckMethod)checkMethodI;
3082*35238bceSAndroid Build Coastguard Worker                 TestCaseGroup *const checkMethodGroup =
3083*35238bceSAndroid Build Coastguard Worker                     new TestCaseGroup(m_context, UniformValueCase::getCheckMethodName(checkMethod),
3084*35238bceSAndroid Build Coastguard Worker                                       UniformValueCase::getCheckMethodDescription(checkMethod));
3085*35238bceSAndroid Build Coastguard Worker                 initialValuesGroup->addChild(checkMethodGroup);
3086*35238bceSAndroid Build Coastguard Worker 
3087*35238bceSAndroid Build Coastguard Worker                 for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST;
3088*35238bceSAndroid Build Coastguard Worker                      collectionGroupNdx++)
3089*35238bceSAndroid Build Coastguard Worker                 {
3090*35238bceSAndroid Build Coastguard Worker                     const UniformCollectionGroup &collectionGroup = defaultUniformCollections[collectionGroupNdx];
3091*35238bceSAndroid Build Coastguard Worker                     TestCaseGroup *const collectionTestGroup =
3092*35238bceSAndroid Build Coastguard Worker                         new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
3093*35238bceSAndroid Build Coastguard Worker                     checkMethodGroup->addChild(collectionTestGroup);
3094*35238bceSAndroid Build Coastguard Worker 
3095*35238bceSAndroid Build Coastguard Worker                     for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
3096*35238bceSAndroid Build Coastguard Worker                     {
3097*35238bceSAndroid Build Coastguard Worker                         const UniformCollectionCase &collectionCase = collectionGroup.cases[collectionNdx];
3098*35238bceSAndroid Build Coastguard Worker                         const string collName                       = collectionCase.namePrefix;
3099*35238bceSAndroid Build Coastguard Worker                         const SharedPtr<const UniformCollection> &uniformCollection = collectionCase.uniformCollection;
3100*35238bceSAndroid Build Coastguard Worker                         const bool containsBooleans =
3101*35238bceSAndroid Build Coastguard Worker                             uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
3102*35238bceSAndroid Build Coastguard Worker                         const bool varyBoolApiType = checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM &&
3103*35238bceSAndroid Build Coastguard Worker                                                      containsBooleans &&
3104*35238bceSAndroid Build Coastguard Worker                                                      (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC ||
3105*35238bceSAndroid Build Coastguard Worker                                                       collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
3106*35238bceSAndroid Build Coastguard Worker                         const int numBoolVariations = varyBoolApiType ? 3 : 1;
3107*35238bceSAndroid Build Coastguard Worker 
3108*35238bceSAndroid Build Coastguard Worker                         if (checkMethod == UniformValueCase::CHECKMETHOD_RENDER &&
3109*35238bceSAndroid Build Coastguard Worker                             uniformCollection->containsSeveralSamplerTypes())
3110*35238bceSAndroid Build Coastguard Worker                             continue; // \note Samplers' initial API values (i.e. their texture units) are 0, and no two samplers of different types shall have same unit when rendering.
3111*35238bceSAndroid Build Coastguard Worker 
3112*35238bceSAndroid Build Coastguard Worker                         for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
3113*35238bceSAndroid Build Coastguard Worker                         {
3114*35238bceSAndroid Build Coastguard Worker                             const uint32_t booleanTypeFeat =
3115*35238bceSAndroid Build Coastguard Worker                                 booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT :
3116*35238bceSAndroid Build Coastguard Worker                                 booleanTypeI == 2 ? UniformCase::FEATURE_BOOLEANAPITYPE_UINT :
3117*35238bceSAndroid Build Coastguard Worker                                                     0;
3118*35238bceSAndroid Build Coastguard Worker                             const char *const booleanTypeName = booleanTypeI == 1 ? "int" :
3119*35238bceSAndroid Build Coastguard Worker                                                                 booleanTypeI == 2 ? "uint" :
3120*35238bceSAndroid Build Coastguard Worker                                                                                     "float";
3121*35238bceSAndroid Build Coastguard Worker                             const string nameWithApiType =
3122*35238bceSAndroid Build Coastguard Worker                                 varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;
3123*35238bceSAndroid Build Coastguard Worker 
3124*35238bceSAndroid Build Coastguard Worker                             for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
3125*35238bceSAndroid Build Coastguard Worker                             {
3126*35238bceSAndroid Build Coastguard Worker                                 const string name = nameWithApiType + getCaseShaderTypeName((CaseShaderType)shaderType);
3127*35238bceSAndroid Build Coastguard Worker                                 collectionTestGroup->addChild(new UniformValueCase(
3128*35238bceSAndroid Build Coastguard Worker                                     m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
3129*35238bceSAndroid Build Coastguard Worker                                     UniformValueCase::VALUETOCHECK_INITIAL, checkMethod,
3130*35238bceSAndroid Build Coastguard Worker                                     UniformValueCase::ASSIGNMETHOD_LAST, booleanTypeFeat));
3131*35238bceSAndroid Build Coastguard Worker                             }
3132*35238bceSAndroid Build Coastguard Worker                         }
3133*35238bceSAndroid Build Coastguard Worker                     }
3134*35238bceSAndroid Build Coastguard Worker                 }
3135*35238bceSAndroid Build Coastguard Worker             }
3136*35238bceSAndroid Build Coastguard Worker         }
3137*35238bceSAndroid Build Coastguard Worker 
3138*35238bceSAndroid Build Coastguard Worker         // Cases that first assign values to each uniform, then check the values with glGetUniform*() or by rendering.
3139*35238bceSAndroid Build Coastguard Worker 
3140*35238bceSAndroid Build Coastguard Worker         {
3141*35238bceSAndroid Build Coastguard Worker             TestCaseGroup *const assignedValuesGroup = new TestCaseGroup(
3142*35238bceSAndroid Build Coastguard Worker                 m_context, UniformValueCase::getValueToCheckName(UniformValueCase::VALUETOCHECK_ASSIGNED),
3143*35238bceSAndroid Build Coastguard Worker                 UniformValueCase::getValueToCheckDescription(UniformValueCase::VALUETOCHECK_ASSIGNED));
3144*35238bceSAndroid Build Coastguard Worker             valueGroup->addChild(assignedValuesGroup);
3145*35238bceSAndroid Build Coastguard Worker 
3146*35238bceSAndroid Build Coastguard Worker             for (int assignMethodI = 0; assignMethodI < (int)UniformValueCase::ASSIGNMETHOD_LAST; assignMethodI++)
3147*35238bceSAndroid Build Coastguard Worker             {
3148*35238bceSAndroid Build Coastguard Worker                 const UniformValueCase::AssignMethod assignMethod = (UniformValueCase::AssignMethod)assignMethodI;
3149*35238bceSAndroid Build Coastguard Worker                 TestCaseGroup *const assignMethodGroup =
3150*35238bceSAndroid Build Coastguard Worker                     new TestCaseGroup(m_context, UniformValueCase::getAssignMethodName(assignMethod),
3151*35238bceSAndroid Build Coastguard Worker                                       UniformValueCase::getAssignMethodDescription(assignMethod));
3152*35238bceSAndroid Build Coastguard Worker                 assignedValuesGroup->addChild(assignMethodGroup);
3153*35238bceSAndroid Build Coastguard Worker 
3154*35238bceSAndroid Build Coastguard Worker                 for (int checkMethodI = 0; checkMethodI < (int)UniformValueCase::CHECKMETHOD_LAST; checkMethodI++)
3155*35238bceSAndroid Build Coastguard Worker                 {
3156*35238bceSAndroid Build Coastguard Worker                     const UniformValueCase::CheckMethod checkMethod = (UniformValueCase::CheckMethod)checkMethodI;
3157*35238bceSAndroid Build Coastguard Worker                     TestCaseGroup *const checkMethodGroup =
3158*35238bceSAndroid Build Coastguard Worker                         new TestCaseGroup(m_context, UniformValueCase::getCheckMethodName(checkMethod),
3159*35238bceSAndroid Build Coastguard Worker                                           UniformValueCase::getCheckMethodDescription(checkMethod));
3160*35238bceSAndroid Build Coastguard Worker                     assignMethodGroup->addChild(checkMethodGroup);
3161*35238bceSAndroid Build Coastguard Worker 
3162*35238bceSAndroid Build Coastguard Worker                     for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST;
3163*35238bceSAndroid Build Coastguard Worker                          collectionGroupNdx++)
3164*35238bceSAndroid Build Coastguard Worker                     {
3165*35238bceSAndroid Build Coastguard Worker                         const int numArrayFirstElemNameCases =
3166*35238bceSAndroid Build Coastguard Worker                             checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM &&
3167*35238bceSAndroid Build Coastguard Worker                                     collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY ?
3168*35238bceSAndroid Build Coastguard Worker                                 2 :
3169*35238bceSAndroid Build Coastguard Worker                                 1;
3170*35238bceSAndroid Build Coastguard Worker 
3171*35238bceSAndroid Build Coastguard Worker                         for (int referToFirstArrayElemWithoutIndexI = 0;
3172*35238bceSAndroid Build Coastguard Worker                              referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases;
3173*35238bceSAndroid Build Coastguard Worker                              referToFirstArrayElemWithoutIndexI++)
3174*35238bceSAndroid Build Coastguard Worker                         {
3175*35238bceSAndroid Build Coastguard Worker                             const UniformCollectionGroup &collectionGroup =
3176*35238bceSAndroid Build Coastguard Worker                                 defaultUniformCollections[collectionGroupNdx];
3177*35238bceSAndroid Build Coastguard Worker                             const string collectionGroupName =
3178*35238bceSAndroid Build Coastguard Worker                                 collectionGroup.name +
3179*35238bceSAndroid Build Coastguard Worker                                 (referToFirstArrayElemWithoutIndexI == 0 ? "" : "_first_elem_without_brackets");
3180*35238bceSAndroid Build Coastguard Worker                             TestCaseGroup *collectionTestGroup = DE_NULL;
3181*35238bceSAndroid Build Coastguard Worker 
3182*35238bceSAndroid Build Coastguard Worker                             for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size();
3183*35238bceSAndroid Build Coastguard Worker                                  collectionNdx++)
3184*35238bceSAndroid Build Coastguard Worker                             {
3185*35238bceSAndroid Build Coastguard Worker                                 const UniformCollectionCase &collectionCase = collectionGroup.cases[collectionNdx];
3186*35238bceSAndroid Build Coastguard Worker                                 const string collName                       = collectionCase.namePrefix;
3187*35238bceSAndroid Build Coastguard Worker                                 const SharedPtr<const UniformCollection> &uniformCollection =
3188*35238bceSAndroid Build Coastguard Worker                                     collectionCase.uniformCollection;
3189*35238bceSAndroid Build Coastguard Worker                                 const bool containsBooleans =
3190*35238bceSAndroid Build Coastguard Worker                                     uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
3191*35238bceSAndroid Build Coastguard Worker                                 const bool varyBoolApiType = checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM &&
3192*35238bceSAndroid Build Coastguard Worker                                                              containsBooleans &&
3193*35238bceSAndroid Build Coastguard Worker                                                              (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC ||
3194*35238bceSAndroid Build Coastguard Worker                                                               collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
3195*35238bceSAndroid Build Coastguard Worker                                 const int numBoolVariations = varyBoolApiType ? 3 : 1;
3196*35238bceSAndroid Build Coastguard Worker                                 const bool containsMatrices =
3197*35238bceSAndroid Build Coastguard Worker                                     uniformCollection->containsMatchingBasicType(glu::isDataTypeMatrix);
3198*35238bceSAndroid Build Coastguard Worker                                 const bool varyMatrixMode =
3199*35238bceSAndroid Build Coastguard Worker                                     containsMatrices && (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC ||
3200*35238bceSAndroid Build Coastguard Worker                                                          collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
3201*35238bceSAndroid Build Coastguard Worker                                 const int numMatVariations = varyMatrixMode ? 2 : 1;
3202*35238bceSAndroid Build Coastguard Worker 
3203*35238bceSAndroid Build Coastguard Worker                                 if (containsMatrices && assignMethod != UniformValueCase::ASSIGNMETHOD_POINTER)
3204*35238bceSAndroid Build Coastguard Worker                                     continue;
3205*35238bceSAndroid Build Coastguard Worker 
3206*35238bceSAndroid Build Coastguard Worker                                 for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
3207*35238bceSAndroid Build Coastguard Worker                                 {
3208*35238bceSAndroid Build Coastguard Worker                                     const uint32_t booleanTypeFeat =
3209*35238bceSAndroid Build Coastguard Worker                                         booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT :
3210*35238bceSAndroid Build Coastguard Worker                                         booleanTypeI == 2 ? UniformCase::FEATURE_BOOLEANAPITYPE_UINT :
3211*35238bceSAndroid Build Coastguard Worker                                                             0;
3212*35238bceSAndroid Build Coastguard Worker                                     const char *const booleanTypeName = booleanTypeI == 1 ? "int" :
3213*35238bceSAndroid Build Coastguard Worker                                                                         booleanTypeI == 2 ? "uint" :
3214*35238bceSAndroid Build Coastguard Worker                                                                                             "float";
3215*35238bceSAndroid Build Coastguard Worker                                     const string nameWithBoolType =
3216*35238bceSAndroid Build Coastguard Worker                                         varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;
3217*35238bceSAndroid Build Coastguard Worker 
3218*35238bceSAndroid Build Coastguard Worker                                     for (int matrixTypeI = 0; matrixTypeI < numMatVariations; matrixTypeI++)
3219*35238bceSAndroid Build Coastguard Worker                                     {
3220*35238bceSAndroid Build Coastguard Worker                                         const string nameWithMatrixType =
3221*35238bceSAndroid Build Coastguard Worker                                             nameWithBoolType + (matrixTypeI == 1 ? "row_major_" : "");
3222*35238bceSAndroid Build Coastguard Worker 
3223*35238bceSAndroid Build Coastguard Worker                                         for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
3224*35238bceSAndroid Build Coastguard Worker                                         {
3225*35238bceSAndroid Build Coastguard Worker                                             const string name =
3226*35238bceSAndroid Build Coastguard Worker                                                 nameWithMatrixType + getCaseShaderTypeName((CaseShaderType)shaderType);
3227*35238bceSAndroid Build Coastguard Worker                                             const uint32_t arrayFirstElemNameNoIndexFeat =
3228*35238bceSAndroid Build Coastguard Worker                                                 referToFirstArrayElemWithoutIndexI == 0 ?
3229*35238bceSAndroid Build Coastguard Worker                                                     0 :
3230*35238bceSAndroid Build Coastguard Worker                                                     UniformCase::FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX;
3231*35238bceSAndroid Build Coastguard Worker 
3232*35238bceSAndroid Build Coastguard Worker                                             // skip empty groups by creating groups on demand
3233*35238bceSAndroid Build Coastguard Worker                                             if (!collectionTestGroup)
3234*35238bceSAndroid Build Coastguard Worker                                             {
3235*35238bceSAndroid Build Coastguard Worker                                                 collectionTestGroup =
3236*35238bceSAndroid Build Coastguard Worker                                                     new TestCaseGroup(m_context, collectionGroupName.c_str(), "");
3237*35238bceSAndroid Build Coastguard Worker                                                 checkMethodGroup->addChild(collectionTestGroup);
3238*35238bceSAndroid Build Coastguard Worker                                             }
3239*35238bceSAndroid Build Coastguard Worker 
3240*35238bceSAndroid Build Coastguard Worker                                             collectionTestGroup->addChild(new UniformValueCase(
3241*35238bceSAndroid Build Coastguard Worker                                                 m_context, name.c_str(), "", (CaseShaderType)shaderType,
3242*35238bceSAndroid Build Coastguard Worker                                                 uniformCollection, UniformValueCase::VALUETOCHECK_ASSIGNED, checkMethod,
3243*35238bceSAndroid Build Coastguard Worker                                                 assignMethod,
3244*35238bceSAndroid Build Coastguard Worker                                                 booleanTypeFeat | arrayFirstElemNameNoIndexFeat |
3245*35238bceSAndroid Build Coastguard Worker                                                     (matrixTypeI == 1 ? UniformCase::FEATURE_MATRIXMODE_ROWMAJOR : 0)));
3246*35238bceSAndroid Build Coastguard Worker                                         }
3247*35238bceSAndroid Build Coastguard Worker                                     }
3248*35238bceSAndroid Build Coastguard Worker                                 }
3249*35238bceSAndroid Build Coastguard Worker                             }
3250*35238bceSAndroid Build Coastguard Worker                         }
3251*35238bceSAndroid Build Coastguard Worker                     }
3252*35238bceSAndroid Build Coastguard Worker                 }
3253*35238bceSAndroid Build Coastguard Worker             }
3254*35238bceSAndroid Build Coastguard Worker 
3255*35238bceSAndroid Build Coastguard Worker             // Cases assign multiple basic-array elements with one glUniform*v() (i.e. the count parameter is bigger than 1).
3256*35238bceSAndroid Build Coastguard Worker 
3257*35238bceSAndroid Build Coastguard Worker             {
3258*35238bceSAndroid Build Coastguard Worker                 static const struct
3259*35238bceSAndroid Build Coastguard Worker                 {
3260*35238bceSAndroid Build Coastguard Worker                     UniformCase::Feature arrayAssignMode;
3261*35238bceSAndroid Build Coastguard Worker                     const char *name;
3262*35238bceSAndroid Build Coastguard Worker                     const char *description;
3263*35238bceSAndroid Build Coastguard Worker                 } arrayAssignGroups[] = {{UniformCase::FEATURE_ARRAYASSIGN_FULL, "basic_array_assign_full",
3264*35238bceSAndroid Build Coastguard Worker                                           "Assign entire basic-type arrays per glUniform*v() call"},
3265*35238bceSAndroid Build Coastguard Worker                                          {UniformCase::FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO, "basic_array_assign_partial",
3266*35238bceSAndroid Build Coastguard Worker                                           "Assign two elements of a basic-type array per glUniform*v() call"}};
3267*35238bceSAndroid Build Coastguard Worker 
3268*35238bceSAndroid Build Coastguard Worker                 for (int arrayAssignGroupNdx = 0; arrayAssignGroupNdx < DE_LENGTH_OF_ARRAY(arrayAssignGroups);
3269*35238bceSAndroid Build Coastguard Worker                      arrayAssignGroupNdx++)
3270*35238bceSAndroid Build Coastguard Worker                 {
3271*35238bceSAndroid Build Coastguard Worker                     UniformCase::Feature arrayAssignMode = arrayAssignGroups[arrayAssignGroupNdx].arrayAssignMode;
3272*35238bceSAndroid Build Coastguard Worker                     const char *const groupName          = arrayAssignGroups[arrayAssignGroupNdx].name;
3273*35238bceSAndroid Build Coastguard Worker                     const char *const groupDesc          = arrayAssignGroups[arrayAssignGroupNdx].description;
3274*35238bceSAndroid Build Coastguard Worker 
3275*35238bceSAndroid Build Coastguard Worker                     TestCaseGroup *const curArrayAssignGroup = new TestCaseGroup(m_context, groupName, groupDesc);
3276*35238bceSAndroid Build Coastguard Worker                     assignedValuesGroup->addChild(curArrayAssignGroup);
3277*35238bceSAndroid Build Coastguard Worker 
3278*35238bceSAndroid Build Coastguard Worker                     static const int basicArrayCollectionGroups[] = {UNIFORMCOLLECTIONS_BASIC_ARRAY,
3279*35238bceSAndroid Build Coastguard Worker                                                                      UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT,
3280*35238bceSAndroid Build Coastguard Worker                                                                      UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY};
3281*35238bceSAndroid Build Coastguard Worker 
3282*35238bceSAndroid Build Coastguard Worker                     for (int collectionGroupNdx = 0;
3283*35238bceSAndroid Build Coastguard Worker                          collectionGroupNdx < DE_LENGTH_OF_ARRAY(basicArrayCollectionGroups); collectionGroupNdx++)
3284*35238bceSAndroid Build Coastguard Worker                     {
3285*35238bceSAndroid Build Coastguard Worker                         const UniformCollectionGroup &collectionGroup =
3286*35238bceSAndroid Build Coastguard Worker                             defaultUniformCollections[basicArrayCollectionGroups[collectionGroupNdx]];
3287*35238bceSAndroid Build Coastguard Worker                         TestCaseGroup *const collectionTestGroup =
3288*35238bceSAndroid Build Coastguard Worker                             new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
3289*35238bceSAndroid Build Coastguard Worker                         curArrayAssignGroup->addChild(collectionTestGroup);
3290*35238bceSAndroid Build Coastguard Worker 
3291*35238bceSAndroid Build Coastguard Worker                         for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
3292*35238bceSAndroid Build Coastguard Worker                         {
3293*35238bceSAndroid Build Coastguard Worker                             const UniformCollectionCase &collectionCase = collectionGroup.cases[collectionNdx];
3294*35238bceSAndroid Build Coastguard Worker                             const string collName                       = collectionCase.namePrefix;
3295*35238bceSAndroid Build Coastguard Worker                             const SharedPtr<const UniformCollection> &uniformCollection =
3296*35238bceSAndroid Build Coastguard Worker                                 collectionCase.uniformCollection;
3297*35238bceSAndroid Build Coastguard Worker 
3298*35238bceSAndroid Build Coastguard Worker                             for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
3299*35238bceSAndroid Build Coastguard Worker                             {
3300*35238bceSAndroid Build Coastguard Worker                                 const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
3301*35238bceSAndroid Build Coastguard Worker                                 collectionTestGroup->addChild(new UniformValueCase(
3302*35238bceSAndroid Build Coastguard Worker                                     m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
3303*35238bceSAndroid Build Coastguard Worker                                     UniformValueCase::VALUETOCHECK_ASSIGNED, UniformValueCase::CHECKMETHOD_GET_UNIFORM,
3304*35238bceSAndroid Build Coastguard Worker                                     UniformValueCase::ASSIGNMETHOD_POINTER, arrayAssignMode));
3305*35238bceSAndroid Build Coastguard Worker                             }
3306*35238bceSAndroid Build Coastguard Worker                         }
3307*35238bceSAndroid Build Coastguard Worker                     }
3308*35238bceSAndroid Build Coastguard Worker                 }
3309*35238bceSAndroid Build Coastguard Worker             }
3310*35238bceSAndroid Build Coastguard Worker 
3311*35238bceSAndroid Build Coastguard Worker             // Value checking cases when unused uniforms are present.
3312*35238bceSAndroid Build Coastguard Worker 
3313*35238bceSAndroid Build Coastguard Worker             {
3314*35238bceSAndroid Build Coastguard Worker                 TestCaseGroup *const unusedUniformsGroup =
3315*35238bceSAndroid Build Coastguard Worker                     new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
3316*35238bceSAndroid Build Coastguard Worker                 assignedValuesGroup->addChild(unusedUniformsGroup);
3317*35238bceSAndroid Build Coastguard Worker 
3318*35238bceSAndroid Build Coastguard Worker                 const UniformCollectionGroup &collectionGroup =
3319*35238bceSAndroid Build Coastguard Worker                     defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];
3320*35238bceSAndroid Build Coastguard Worker 
3321*35238bceSAndroid Build Coastguard Worker                 for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
3322*35238bceSAndroid Build Coastguard Worker                 {
3323*35238bceSAndroid Build Coastguard Worker                     const UniformCollectionCase &collectionCase                 = collectionGroup.cases[collectionNdx];
3324*35238bceSAndroid Build Coastguard Worker                     const string collName                                       = collectionCase.namePrefix;
3325*35238bceSAndroid Build Coastguard Worker                     const SharedPtr<const UniformCollection> &uniformCollection = collectionCase.uniformCollection;
3326*35238bceSAndroid Build Coastguard Worker 
3327*35238bceSAndroid Build Coastguard Worker                     for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
3328*35238bceSAndroid Build Coastguard Worker                     {
3329*35238bceSAndroid Build Coastguard Worker                         const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
3330*35238bceSAndroid Build Coastguard Worker                         unusedUniformsGroup->addChild(new UniformValueCase(
3331*35238bceSAndroid Build Coastguard Worker                             m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
3332*35238bceSAndroid Build Coastguard Worker                             UniformValueCase::VALUETOCHECK_ASSIGNED, UniformValueCase::CHECKMETHOD_GET_UNIFORM,
3333*35238bceSAndroid Build Coastguard Worker                             UniformValueCase::ASSIGNMETHOD_POINTER,
3334*35238bceSAndroid Build Coastguard Worker                             UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX |
3335*35238bceSAndroid Build Coastguard Worker                                 UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER));
3336*35238bceSAndroid Build Coastguard Worker                     }
3337*35238bceSAndroid Build Coastguard Worker                 }
3338*35238bceSAndroid Build Coastguard Worker             }
3339*35238bceSAndroid Build Coastguard Worker         }
3340*35238bceSAndroid Build Coastguard Worker     }
3341*35238bceSAndroid Build Coastguard Worker 
3342*35238bceSAndroid Build Coastguard Worker     // Random cases.
3343*35238bceSAndroid Build Coastguard Worker 
3344*35238bceSAndroid Build Coastguard Worker     {
3345*35238bceSAndroid Build Coastguard Worker         const int numRandomCases         = 100;
3346*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const randomGroup = new TestCaseGroup(m_context, "random", "Random cases");
3347*35238bceSAndroid Build Coastguard Worker         addChild(randomGroup);
3348*35238bceSAndroid Build Coastguard Worker 
3349*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < numRandomCases; ndx++)
3350*35238bceSAndroid Build Coastguard Worker             randomGroup->addChild(new RandomUniformCase(m_context, de::toString(ndx).c_str(), "", (uint32_t)ndx));
3351*35238bceSAndroid Build Coastguard Worker     }
3352*35238bceSAndroid Build Coastguard Worker }
3353*35238bceSAndroid Build Coastguard Worker 
3354*35238bceSAndroid Build Coastguard Worker } // namespace Functional
3355*35238bceSAndroid Build Coastguard Worker } // namespace gles3
3356*35238bceSAndroid Build Coastguard Worker } // namespace deqp
3357