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