Merge "Fix color change verification in dithering tests" into nougat-cts-dev am:...
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fUniformBlockTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Uniform block tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es3fUniformBlockTests.hpp"
25 #include "glsUniformBlockCase.hpp"
26 #include "glsRandomUniformBlockCase.hpp"
27 #include "tcuCommandLine.hpp"
28 #include "deRandom.hpp"
29 #include "deStringUtil.hpp"
30
31 using std::string;
32 using std::vector;
33
34 namespace deqp
35 {
36 namespace gles3
37 {
38 namespace Functional
39 {
40
41 using gls::UniformBlockCase;
42 using gls::RandomUniformBlockCase;
43 using namespace gls::ub;
44
45 static void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, Context& context, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed)
46 {
47         tcu::TestCaseGroup* group = new tcu::TestCaseGroup(context.getTestContext(), groupName, description);
48         parentGroup->addChild(group);
49
50         baseSeed += (deUint32)context.getTestContext().getCommandLine().getBaseSeed();
51
52         for (int ndx = 0; ndx < numCases; ndx++)
53                 group->addChild(new RandomUniformBlockCase(context.getTestContext(), context.getRenderContext(), glu::GLSL_VERSION_300_ES,
54                                                                                                    de::toString(ndx).c_str(), "", bufferMode, features, (deUint32)ndx+baseSeed));
55 }
56
57 class BlockBasicTypeCase : public UniformBlockCase
58 {
59 public:
60         BlockBasicTypeCase (Context& context, const char* name, const char* description, const VarType& type, deUint32 layoutFlags, int numInstances)
61                 : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, BUFFERMODE_PER_BLOCK)
62         {
63                 UniformBlock& block = m_interface.allocBlock("Block");
64                 block.addUniform(Uniform("var", type, 0));
65                 block.setFlags(layoutFlags);
66
67                 if (numInstances > 0)
68                 {
69                         block.setArraySize(numInstances);
70                         block.setInstanceName("block");
71                 }
72         }
73 };
74
75 static void createBlockBasicTypeCases (tcu::TestCaseGroup* group, Context& context, const char* name, const VarType& type, deUint32 layoutFlags, int numInstances = 0)
76 {
77         group->addChild(new BlockBasicTypeCase(context, (string(name) + "_vertex").c_str(),             "", type, layoutFlags|DECLARE_VERTEX,                                   numInstances));
78         group->addChild(new BlockBasicTypeCase(context, (string(name) + "_fragment").c_str(),   "", type, layoutFlags|DECLARE_FRAGMENT,                                 numInstances));
79
80         if (!(layoutFlags & LAYOUT_PACKED))
81                 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_both").c_str(),               "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  numInstances));
82 }
83
84 class BlockSingleStructCase : public UniformBlockCase
85 {
86 public:
87         BlockSingleStructCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
88                 : UniformBlockCase      (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
89                 , m_layoutFlags         (layoutFlags)
90                 , m_numInstances        (numInstances)
91         {
92         }
93
94         void init (void)
95         {
96                 StructType& typeS = m_interface.allocStruct("S");
97                 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused.
98                 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
99                 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
100
101                 UniformBlock& block = m_interface.allocBlock("Block");
102                 block.addUniform(Uniform("s", VarType(&typeS), 0));
103                 block.setFlags(m_layoutFlags);
104
105                 if (m_numInstances > 0)
106                 {
107                         block.setInstanceName("block");
108                         block.setArraySize(m_numInstances);
109                 }
110         }
111
112 private:
113         deUint32        m_layoutFlags;
114         int                     m_numInstances;
115 };
116
117 class BlockSingleStructArrayCase : public UniformBlockCase
118 {
119 public:
120         BlockSingleStructArrayCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
121                 : UniformBlockCase      (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
122                 , m_layoutFlags         (layoutFlags)
123                 , m_numInstances        (numInstances)
124         {
125         }
126
127         void init (void)
128         {
129                 StructType& typeS = m_interface.allocStruct("S");
130                 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
131                 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
132                 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
133
134                 UniformBlock& block = m_interface.allocBlock("Block");
135                 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
136                 block.addUniform(Uniform("s", VarType(VarType(&typeS), 3)));
137                 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
138                 block.setFlags(m_layoutFlags);
139
140                 if (m_numInstances > 0)
141                 {
142                         block.setInstanceName("block");
143                         block.setArraySize(m_numInstances);
144                 }
145         }
146
147 private:
148         deUint32        m_layoutFlags;
149         int                     m_numInstances;
150 };
151
152 class BlockSingleNestedStructCase : public UniformBlockCase
153 {
154 public:
155         BlockSingleNestedStructCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
156                 : UniformBlockCase      (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
157                 , m_layoutFlags         (layoutFlags)
158                 , m_numInstances        (numInstances)
159         {
160         }
161
162         void init (void)
163         {
164                 StructType& typeS = m_interface.allocStruct("S");
165                 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
166                 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
167                 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
168
169                 StructType& typeT = m_interface.allocStruct("T");
170                 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
171                 typeT.addMember("b", VarType(&typeS));
172
173                 UniformBlock& block = m_interface.allocBlock("Block");
174                 block.addUniform(Uniform("s", VarType(&typeS), 0));
175                 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
176                 block.addUniform(Uniform("t", VarType(&typeT), 0));
177                 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
178                 block.setFlags(m_layoutFlags);
179
180                 if (m_numInstances > 0)
181                 {
182                         block.setInstanceName("block");
183                         block.setArraySize(m_numInstances);
184                 }
185         }
186
187 private:
188         deUint32        m_layoutFlags;
189         int                     m_numInstances;
190 };
191
192 class BlockSingleNestedStructArrayCase : public UniformBlockCase
193 {
194 public:
195         BlockSingleNestedStructArrayCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
196                 : UniformBlockCase      (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
197                 , m_layoutFlags         (layoutFlags)
198                 , m_numInstances        (numInstances)
199         {
200         }
201
202         void init (void)
203         {
204                 StructType& typeS = m_interface.allocStruct("S");
205                 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
206                 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
207                 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
208
209                 StructType& typeT = m_interface.allocStruct("T");
210                 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
211                 typeT.addMember("b", VarType(VarType(&typeS), 3));
212
213                 UniformBlock& block = m_interface.allocBlock("Block");
214                 block.addUniform(Uniform("s", VarType(&typeS), 0));
215                 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
216                 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0));
217                 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
218                 block.setFlags(m_layoutFlags);
219
220                 if (m_numInstances > 0)
221                 {
222                         block.setInstanceName("block");
223                         block.setArraySize(m_numInstances);
224                 }
225         }
226
227 private:
228         deUint32        m_layoutFlags;
229         int                     m_numInstances;
230 };
231
232 class BlockMultiBasicTypesCase : public UniformBlockCase
233 {
234 public:
235         BlockMultiBasicTypesCase (Context& context, const char* name, const char* description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances)
236                 : UniformBlockCase      (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
237                 , m_flagsA                      (flagsA)
238                 , m_flagsB                      (flagsB)
239                 , m_numInstances        (numInstances)
240         {
241         }
242
243         void init (void)
244         {
245                 UniformBlock& blockA = m_interface.allocBlock("BlockA");
246                 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
247                 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
248                 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
249                 blockA.setInstanceName("blockA");
250                 blockA.setFlags(m_flagsA);
251
252                 UniformBlock& blockB = m_interface.allocBlock("BlockB");
253                 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
254                 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
255                 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
256                 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
257                 blockB.setInstanceName("blockB");
258                 blockB.setFlags(m_flagsB);
259
260                 if (m_numInstances > 0)
261                 {
262                         blockA.setArraySize(m_numInstances);
263                         blockB.setArraySize(m_numInstances);
264                 }
265         }
266
267 private:
268         deUint32        m_flagsA;
269         deUint32        m_flagsB;
270         int                     m_numInstances;
271 };
272
273 class BlockMultiNestedStructCase : public UniformBlockCase
274 {
275 public:
276         BlockMultiNestedStructCase (Context& context, const char* name, const char* description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances)
277                 : UniformBlockCase      (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
278                 , m_flagsA                      (flagsA)
279                 , m_flagsB                      (flagsB)
280                 , m_numInstances        (numInstances)
281         {
282         }
283
284         void init (void)
285         {
286                 StructType& typeS = m_interface.allocStruct("S");
287                 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW));
288                 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
289                 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
290
291                 StructType& typeT = m_interface.allocStruct("T");
292                 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH);
293                 typeT.addMember("b", VarType(&typeS));
294                 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0));
295
296                 UniformBlock& blockA = m_interface.allocBlock("BlockA");
297                 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
298                 blockA.addUniform(Uniform("b", VarType(&typeS)));
299                 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
300                 blockA.setInstanceName("blockA");
301                 blockA.setFlags(m_flagsA);
302
303                 UniformBlock& blockB = m_interface.allocBlock("BlockB");
304                 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
305                 blockB.addUniform(Uniform("b", VarType(&typeT)));
306                 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH));
307                 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
308                 blockB.setInstanceName("blockB");
309                 blockB.setFlags(m_flagsB);
310
311                 if (m_numInstances > 0)
312                 {
313                         blockA.setArraySize(m_numInstances);
314                         blockB.setArraySize(m_numInstances);
315                 }
316         }
317
318 private:
319         deUint32        m_flagsA;
320         deUint32        m_flagsB;
321         int                     m_numInstances;
322 };
323
324 UniformBlockTests::UniformBlockTests (Context& context)
325         : TestCaseGroup(context, "ubo", "Uniform Block tests")
326 {
327 }
328
329 UniformBlockTests::~UniformBlockTests (void)
330 {
331 }
332
333 void UniformBlockTests::init (void)
334 {
335         static const glu::DataType basicTypes[] =
336         {
337                 glu::TYPE_FLOAT,
338                 glu::TYPE_FLOAT_VEC2,
339                 glu::TYPE_FLOAT_VEC3,
340                 glu::TYPE_FLOAT_VEC4,
341                 glu::TYPE_INT,
342                 glu::TYPE_INT_VEC2,
343                 glu::TYPE_INT_VEC3,
344                 glu::TYPE_INT_VEC4,
345                 glu::TYPE_UINT,
346                 glu::TYPE_UINT_VEC2,
347                 glu::TYPE_UINT_VEC3,
348                 glu::TYPE_UINT_VEC4,
349                 glu::TYPE_BOOL,
350                 glu::TYPE_BOOL_VEC2,
351                 glu::TYPE_BOOL_VEC3,
352                 glu::TYPE_BOOL_VEC4,
353                 glu::TYPE_FLOAT_MAT2,
354                 glu::TYPE_FLOAT_MAT3,
355                 glu::TYPE_FLOAT_MAT4,
356                 glu::TYPE_FLOAT_MAT2X3,
357                 glu::TYPE_FLOAT_MAT2X4,
358                 glu::TYPE_FLOAT_MAT3X2,
359                 glu::TYPE_FLOAT_MAT3X4,
360                 glu::TYPE_FLOAT_MAT4X2,
361                 glu::TYPE_FLOAT_MAT4X3
362         };
363
364         static const struct
365         {
366                 const char*             name;
367                 deUint32                flags;
368         } precisionFlags[] =
369         {
370                 { "lowp",               PRECISION_LOW           },
371                 { "mediump",    PRECISION_MEDIUM        },
372                 { "highp",              PRECISION_HIGH          }
373         };
374
375         static const struct
376         {
377                 const char*             name;
378                 deUint32                flags;
379         } layoutFlags[] =
380         {
381                 { "shared",             LAYOUT_SHARED   },
382                 { "packed",             LAYOUT_PACKED   },
383                 { "std140",             LAYOUT_STD140   }
384         };
385
386         static const struct
387         {
388                 const char*             name;
389                 deUint32                flags;
390         } matrixFlags[] =
391         {
392                 { "row_major",          LAYOUT_ROW_MAJOR        },
393                 { "column_major",       LAYOUT_COLUMN_MAJOR }
394         };
395
396         static const struct
397         {
398                 const char*                                                     name;
399                 UniformBlockCase::BufferMode            mode;
400         } bufferModes[] =
401         {
402                 { "per_block_buffer",   UniformBlockCase::BUFFERMODE_PER_BLOCK },
403                 { "single_buffer",              UniformBlockCase::BUFFERMODE_SINGLE     }
404         };
405
406         // ubo.single_basic_type
407         {
408                 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
409                 addChild(singleBasicTypeGroup);
410
411                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
412                 {
413                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
414                         singleBasicTypeGroup->addChild(layoutGroup);
415
416                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
417                         {
418                                 glu::DataType   type            = basicTypes[basicTypeNdx];
419                                 const char*             typeName        = glu::getDataTypeName(type);
420
421                                 if (glu::isDataTypeBoolOrBVec(type))
422                                         createBlockBasicTypeCases(layoutGroup, m_context, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags);
423                                 else
424                                 {
425                                         for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
426                                                 createBlockBasicTypeCases(layoutGroup, m_context, (string(precisionFlags[precNdx].name) + "_" + typeName).c_str(),
427                                                                                                   VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags);
428                                 }
429
430                                 if (glu::isDataTypeMatrix(type))
431                                 {
432                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
433                                         {
434                                                 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
435                                                         createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + precisionFlags[precNdx].name + "_" + typeName).c_str(),
436                                                                                                           VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
437                                         }
438                                 }
439                         }
440                 }
441         }
442
443         // ubo.single_basic_array
444         {
445                 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
446                 addChild(singleBasicArrayGroup);
447
448                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
449                 {
450                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
451                         singleBasicArrayGroup->addChild(layoutGroup);
452
453                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
454                         {
455                                 glu::DataType   type            = basicTypes[basicTypeNdx];
456                                 const char*             typeName        = glu::getDataTypeName(type);
457                                 const int               arraySize       = 3;
458
459                                 createBlockBasicTypeCases(layoutGroup, m_context, typeName,
460                                                                                   VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize),
461                                                                                   layoutFlags[layoutFlagNdx].flags);
462
463                                 if (glu::isDataTypeMatrix(type))
464                                 {
465                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
466                                                 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(),
467                                                                                                   VarType(VarType(type, PRECISION_HIGH), arraySize),
468                                                                                                   layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
469                                 }
470                         }
471                 }
472         }
473
474         // ubo.single_struct
475         {
476                 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
477                 addChild(singleStructGroup);
478
479                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
480                 {
481                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
482                         singleStructGroup->addChild(modeGroup);
483
484                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
485                         {
486                                 for (int isArray = 0; isArray < 2; isArray++)
487                                 {
488                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
489                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
490
491                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
492                                                 continue; // Doesn't make sense to add this variant.
493
494                                         if (isArray)
495                                                 baseName += "_instance_array";
496
497                                         modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_vertex").c_str(),        "", baseFlags|DECLARE_VERTEX,                                   bufferModes[modeNdx].mode, isArray ? 3 : 0));
498                                         modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_fragment").c_str(),      "", baseFlags|DECLARE_FRAGMENT,                                 bufferModes[modeNdx].mode, isArray ? 3 : 0));
499
500                                         if (!(baseFlags & LAYOUT_PACKED))
501                                                 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_both").c_str(),          "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  bufferModes[modeNdx].mode, isArray ? 3 : 0));
502                                 }
503                         }
504                 }
505         }
506
507         // ubo.single_struct_array
508         {
509                 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
510                 addChild(singleStructArrayGroup);
511
512                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
513                 {
514                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
515                         singleStructArrayGroup->addChild(modeGroup);
516
517                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
518                         {
519                                 for (int isArray = 0; isArray < 2; isArray++)
520                                 {
521                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
522                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
523
524                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
525                                                 continue; // Doesn't make sense to add this variant.
526
527                                         if (isArray)
528                                                 baseName += "_instance_array";
529
530                                         modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_vertex").c_str(),   "", baseFlags|DECLARE_VERTEX,                                   bufferModes[modeNdx].mode, isArray ? 3 : 0));
531                                         modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT,                                 bufferModes[modeNdx].mode, isArray ? 3 : 0));
532
533                                         if (!(baseFlags & LAYOUT_PACKED))
534                                                 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_both").c_str(),             "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  bufferModes[modeNdx].mode, isArray ? 3 : 0));
535                                 }
536                         }
537                 }
538         }
539
540         // ubo.single_nested_struct
541         {
542                 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
543                 addChild(singleNestedStructGroup);
544
545                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
546                 {
547                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
548                         singleNestedStructGroup->addChild(modeGroup);
549
550                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
551                         {
552                                 for (int isArray = 0; isArray < 2; isArray++)
553                                 {
554                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
555                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
556
557                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
558                                                 continue; // Doesn't make sense to add this variant.
559
560                                         if (isArray)
561                                                 baseName += "_instance_array";
562
563                                         modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_vertex").c_str(),          "", baseFlags|DECLARE_VERTEX,                                   bufferModes[modeNdx].mode, isArray ? 3 : 0));
564                                         modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_fragment").c_str(),        "", baseFlags|DECLARE_FRAGMENT,                                 bufferModes[modeNdx].mode, isArray ? 3 : 0));
565
566                                         if (!(baseFlags & LAYOUT_PACKED))
567                                                 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_both").c_str(),            "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  bufferModes[modeNdx].mode, isArray ? 3 : 0));
568                                 }
569                         }
570                 }
571         }
572
573         // ubo.single_nested_struct_array
574         {
575                 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
576                 addChild(singleNestedStructArrayGroup);
577
578                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
579                 {
580                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
581                         singleNestedStructArrayGroup->addChild(modeGroup);
582
583                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
584                         {
585                                 for (int isArray = 0; isArray < 2; isArray++)
586                                 {
587                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
588                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
589
590                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
591                                                 continue; // Doesn't make sense to add this variant.
592
593                                         if (isArray)
594                                                 baseName += "_instance_array";
595
596                                         modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_vertex").c_str(),             "", baseFlags|DECLARE_VERTEX,                                   bufferModes[modeNdx].mode, isArray ? 3 : 0));
597                                         modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_fragment").c_str(),   "", baseFlags|DECLARE_FRAGMENT,                                 bufferModes[modeNdx].mode, isArray ? 3 : 0));
598
599                                         if (!(baseFlags & LAYOUT_PACKED))
600                                                 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_both").c_str(),               "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  bufferModes[modeNdx].mode, isArray ? 3 : 0));
601                                 }
602                         }
603                 }
604         }
605
606         // ubo.instance_array_basic_type
607         {
608                 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
609                 addChild(instanceArrayBasicTypeGroup);
610
611                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
612                 {
613                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
614                         instanceArrayBasicTypeGroup->addChild(layoutGroup);
615
616                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
617                         {
618                                 glu::DataType   type                    = basicTypes[basicTypeNdx];
619                                 const char*             typeName                = glu::getDataTypeName(type);
620                                 const int               numInstances    = 3;
621
622                                 createBlockBasicTypeCases(layoutGroup, m_context, typeName,
623                                                                                   VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH),
624                                                                                   layoutFlags[layoutFlagNdx].flags, numInstances);
625
626                                 if (glu::isDataTypeMatrix(type))
627                                 {
628                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
629                                                 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(),
630                                                                                                   VarType(type, PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags,
631                                                                                                   numInstances);
632                                 }
633                         }
634                 }
635         }
636
637         // ubo.multi_basic_types
638         {
639                 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
640                 addChild(multiBasicTypesGroup);
641
642                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
643                 {
644                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
645                         multiBasicTypesGroup->addChild(modeGroup);
646
647                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
648                         {
649                                 for (int isArray = 0; isArray < 2; isArray++)
650                                 {
651                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
652                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
653
654                                         if (isArray)
655                                                 baseName += "_instance_array";
656
657                                         modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_vertex").c_str(),             "", baseFlags|DECLARE_VERTEX,                                   baseFlags|DECLARE_VERTEX,                                       bufferModes[modeNdx].mode, isArray ? 3 : 0));
658                                         modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_fragment").c_str(),   "", baseFlags|DECLARE_FRAGMENT,                                 baseFlags|DECLARE_FRAGMENT,                                     bufferModes[modeNdx].mode, isArray ? 3 : 0));
659
660                                         if (!(baseFlags & LAYOUT_PACKED))
661                                                 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_both").c_str(),               "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,      bufferModes[modeNdx].mode, isArray ? 3 : 0));
662
663                                         modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_mixed").c_str(),              "", baseFlags|DECLARE_VERTEX,                                   baseFlags|DECLARE_FRAGMENT,                                     bufferModes[modeNdx].mode, isArray ? 3 : 0));
664                                 }
665                         }
666                 }
667         }
668
669         // ubo.multi_nested_struct
670         {
671                 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
672                 addChild(multiNestedStructGroup);
673
674                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
675                 {
676                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
677                         multiNestedStructGroup->addChild(modeGroup);
678
679                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
680                         {
681                                 for (int isArray = 0; isArray < 2; isArray++)
682                                 {
683                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
684                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
685
686                                         if (isArray)
687                                                 baseName += "_instance_array";
688
689                                         modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_vertex").c_str(),   "", baseFlags|DECLARE_VERTEX,                                   baseFlags|DECLARE_VERTEX,                                       bufferModes[modeNdx].mode, isArray ? 3 : 0));
690                                         modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT,                                 baseFlags|DECLARE_FRAGMENT,                                     bufferModes[modeNdx].mode, isArray ? 3 : 0));
691
692                                         if (!(baseFlags & LAYOUT_PACKED))
693                                                 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_both").c_str(),             "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,      bufferModes[modeNdx].mode, isArray ? 3 : 0));
694
695                                         modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_mixed").c_str(),    "", baseFlags|DECLARE_VERTEX,                                   baseFlags|DECLARE_FRAGMENT,                                     bufferModes[modeNdx].mode, isArray ? 3 : 0));
696                                 }
697                         }
698                 }
699         }
700
701         // ubo.random
702         {
703                 const deUint32  allShaders              = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS;
704                 const deUint32  allLayouts              = FEATURE_PACKED_LAYOUT|FEATURE_SHARED_LAYOUT|FEATURE_STD140_LAYOUT;
705                 const deUint32  allBasicTypes   = FEATURE_VECTORS|FEATURE_MATRICES;
706                 const deUint32  unused                  = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
707                 const deUint32  matFlags                = FEATURE_MATRIX_LAYOUT;
708                 const deUint32  allFeatures             = ~FEATURE_ARRAYS_OF_ARRAYS;
709
710                 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
711                 addChild(randomGroup);
712
713                 // Basic types.
714                 createRandomCaseGroup(randomGroup, m_context, "scalar_types",   "Scalar types only, per-block buffers",                         UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused,                                                                           25, 0);
715                 createRandomCaseGroup(randomGroup, m_context, "vector_types",   "Scalar and vector types only, per-block buffers",      UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|FEATURE_VECTORS,                                           25, 25);
716                 createRandomCaseGroup(randomGroup, m_context, "basic_types",    "All basic types, per-block buffers",                           UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags,                            25, 50);
717                 createRandomCaseGroup(randomGroup, m_context, "basic_arrays",   "Arrays, per-block buffers",                                            UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS,     25, 50);
718
719                 createRandomCaseGroup(randomGroup, m_context, "basic_instance_arrays",                                  "Basic instance arrays, per-block buffers",                             UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_INSTANCE_ARRAYS,                                                            25, 75);
720                 createRandomCaseGroup(randomGroup, m_context, "nested_structs",                                                 "Nested structs, per-block buffers",                                    UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS,                                                                            25, 100);
721                 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays",                                  "Nested structs, arrays, per-block buffers",                    UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS,                                                     25, 150);
722                 createRandomCaseGroup(randomGroup, m_context, "nested_structs_instance_arrays",                 "Nested structs, instance arrays, per-block buffers",   UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_INSTANCE_ARRAYS,                            25, 125);
723                 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays_instance_arrays",  "Nested structs, instance arrays, per-block buffers",   UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS|FEATURE_INSTANCE_ARRAYS,     25, 175);
724
725                 createRandomCaseGroup(randomGroup, m_context, "all_per_block_buffers",  "All random features, per-block buffers",       UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures,    50, 200);
726                 createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer",              "All random features, shared buffer",           UniformBlockCase::BUFFERMODE_SINGLE,    allFeatures,    50, 250);
727         }
728 }
729
730 } // Functional
731 } // gles3
732 } // deqp