resolve merge conflicts of a9ffcc1 to master
[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 class LinkByBindingCase : public UniformBlockCase
294 {
295 public:
296         LinkByBindingCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, BufferMode bufferMode, int numInstances)
297                 : UniformBlockCase      (testCtx, name, description, bufferMode, LOAD_FULL_MATRIX)
298         {
299                 UniformBlock& blockA = m_interface.allocBlock("TestBlock");
300                 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
301                 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
302                 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
303                 blockA.setFlags(LAYOUT_STD140|DECLARE_VERTEX);
304
305                 UniformBlock& blockB = m_interface.allocBlock("TestBlock");
306                 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
307                 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
308                 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
309                 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
310                 blockB.setFlags(LAYOUT_STD140|DECLARE_FRAGMENT);
311
312                 if (numInstances > 0)
313                 {
314                         blockA.setInstanceName("testBlock");
315                         blockA.setArraySize(numInstances);
316                         blockB.setInstanceName("testBlock");
317                         blockB.setArraySize(numInstances);
318                 }
319
320                 init();
321         }
322 };
323
324 void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed)
325 {
326         tcu::TestCaseGroup* group = new tcu::TestCaseGroup(testCtx, groupName, description);
327         parentGroup->addChild(group);
328
329         baseSeed += (deUint32)testCtx.getCommandLine().getBaseSeed();
330
331         for (int ndx = 0; ndx < numCases; ndx++)
332                 group->addChild(new RandomUniformBlockCase(testCtx, de::toString(ndx), "", bufferMode, features, (deUint32)ndx + baseSeed));
333 }
334
335 // UniformBlockTests
336
337 class UniformBlockTests : public tcu::TestCaseGroup
338 {
339 public:
340                                                         UniformBlockTests               (tcu::TestContext& testCtx);
341                                                         ~UniformBlockTests              (void);
342
343         void                                    init                                    (void);
344
345 private:
346                                                         UniformBlockTests               (const UniformBlockTests& other);
347         UniformBlockTests&              operator=                               (const UniformBlockTests& other);
348 };
349
350 UniformBlockTests::UniformBlockTests (tcu::TestContext& testCtx)
351         : TestCaseGroup(testCtx, "ubo", "Uniform Block tests")
352 {
353 }
354
355 UniformBlockTests::~UniformBlockTests (void)
356 {
357 }
358
359 void UniformBlockTests::init (void)
360 {
361         static const glu::DataType basicTypes[] =
362         {
363                 glu::TYPE_FLOAT,
364                 glu::TYPE_FLOAT_VEC2,
365                 glu::TYPE_FLOAT_VEC3,
366                 glu::TYPE_FLOAT_VEC4,
367                 glu::TYPE_INT,
368                 glu::TYPE_INT_VEC2,
369                 glu::TYPE_INT_VEC3,
370                 glu::TYPE_INT_VEC4,
371                 glu::TYPE_UINT,
372                 glu::TYPE_UINT_VEC2,
373                 glu::TYPE_UINT_VEC3,
374                 glu::TYPE_UINT_VEC4,
375                 glu::TYPE_BOOL,
376                 glu::TYPE_BOOL_VEC2,
377                 glu::TYPE_BOOL_VEC3,
378                 glu::TYPE_BOOL_VEC4,
379                 glu::TYPE_FLOAT_MAT2,
380                 glu::TYPE_FLOAT_MAT3,
381                 glu::TYPE_FLOAT_MAT4,
382                 glu::TYPE_FLOAT_MAT2X3,
383                 glu::TYPE_FLOAT_MAT2X4,
384                 glu::TYPE_FLOAT_MAT3X2,
385                 glu::TYPE_FLOAT_MAT3X4,
386                 glu::TYPE_FLOAT_MAT4X2,
387                 glu::TYPE_FLOAT_MAT4X3
388         };
389
390         static const struct
391         {
392                 const std::string       name;
393                 deUint32                        flags;
394         } precisionFlags[] =
395         {
396                 // TODO remove PRECISION_LOW because both PRECISION_LOW and PRECISION_MEDIUM means relaxed precision?
397                 { "lowp",               PRECISION_LOW           },
398                 { "mediump",    PRECISION_MEDIUM        },
399                 { "highp",              PRECISION_HIGH          }
400         };
401
402         static const struct
403         {
404                 const char*                     name;
405                 deUint32                        flags;
406         } layoutFlags[] =
407         {
408                 { "std140",             LAYOUT_STD140   }
409         };
410
411         static const struct
412         {
413                 const std::string       name;
414                 deUint32                        flags;
415         } matrixFlags[] =
416         {
417                 { "row_major",          LAYOUT_ROW_MAJOR        },
418                 { "column_major",       LAYOUT_COLUMN_MAJOR }
419         };
420
421         static const struct
422         {
423                 const char*                                                     name;
424                 UniformBlockCase::BufferMode            mode;
425         } bufferModes[] =
426         {
427                 { "per_block_buffer",   UniformBlockCase::BUFFERMODE_PER_BLOCK },
428                 { "single_buffer",              UniformBlockCase::BUFFERMODE_SINGLE     }
429         };
430
431         // ubo.2_level_array
432         {
433                 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array", "2-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                       childSize       = 4;
446                                 const int                       parentSize      = 3;
447                                 const VarType           childType       (VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), childSize);
448                                 const VarType           parentType      (childType, parentSize);
449
450                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
451
452                                 if (glu::isDataTypeMatrix(type))
453                                 {
454                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
455                                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, (std::string(matrixFlags[matFlagNdx].name) + "_" + typeName),
456                                                                                                   parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
457                                 }
458                         }
459                 }
460         }
461
462         // ubo.3_level_array
463         {
464                 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "3_level_array", "3-level basic array variable in single buffer");
465                 addChild(nestedArrayGroup);
466
467                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
468                 {
469                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
470                         nestedArrayGroup->addChild(layoutGroup);
471
472                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
473                         {
474                                 const glu::DataType     type            = basicTypes[basicTypeNdx];
475                                 const char*                     typeName        = glu::getDataTypeName(type);
476                                 const int                       childSize0      = 2;
477                                 const int                       childSize1      = 4;
478                                 const int                       parentSize      = 3;
479                                 const VarType           childType0      (VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), childSize0);
480                                 const VarType           childType1      (childType0, childSize1);
481                                 const VarType           parentType      (childType1, parentSize);
482
483                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
484
485                                 if (glu::isDataTypeMatrix(type))
486                                 {
487                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
488                                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, (std::string(matrixFlags[matFlagNdx].name) + "_" + typeName),
489                                                                                                   parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
490                                 }
491                         }
492                 }
493         }
494
495         // ubo.2_level_struct_array
496         {
497                 tcu::TestCaseGroup* structArrayArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_struct_array", "Struct array in one uniform block");
498                 addChild(structArrayArrayGroup);
499
500                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
501                 {
502                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
503                         structArrayArrayGroup->addChild(modeGroup);
504
505                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
506                         {
507                                 for (int isArray = 0; isArray < 2; isArray++)
508                                 {
509                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
510                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
511
512                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
513                                                 continue; // Doesn't make sense to add this variant.
514
515                                         if (isArray)
516                                                 baseName += "_instance_array";
517
518                                         modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex"),                           "", baseFlags|DECLARE_VERTEX,                                   bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
519                                         modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_fragment"),                         "", baseFlags|DECLARE_FRAGMENT,                                 bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
520                                         modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_both"),                                     "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
521                                         modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex_comp_access"),       "", baseFlags|DECLARE_VERTEX,                                   bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
522                                         modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_fragment_comp_access"),     "", baseFlags|DECLARE_FRAGMENT,                                 bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
523                                         modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_both_comp_access"),         "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
524                                 }
525                         }
526                 }
527         }
528
529         // ubo.single_basic_type
530         {
531                 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
532                 addChild(singleBasicTypeGroup);
533
534                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
535                 {
536                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
537                         singleBasicTypeGroup->addChild(layoutGroup);
538
539                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
540                         {
541                                 glu::DataType   type            = basicTypes[basicTypeNdx];
542                                 const char*             typeName        = glu::getDataTypeName(type);
543
544                                 if (glu::isDataTypeBoolOrBVec(type))
545                                         createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags);
546                                 else
547                                 {
548                                         for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
549                                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, precisionFlags[precNdx].name + "_" + typeName,
550                                                                                                   VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags);
551                                 }
552
553                                 if (glu::isDataTypeMatrix(type))
554                                 {
555                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
556                                         {
557                                                 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
558                                                         createBlockBasicTypeCases(layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + precisionFlags[precNdx].name + "_" + typeName,
559                                                                                                           VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
560                                         }
561                                 }
562                         }
563                 }
564         }
565
566         // ubo.single_basic_array
567         {
568                 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
569                 addChild(singleBasicArrayGroup);
570
571                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
572                 {
573                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
574                         singleBasicArrayGroup->addChild(layoutGroup);
575
576                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
577                         {
578                                 glu::DataType   type            = basicTypes[basicTypeNdx];
579                                 const char*             typeName        = glu::getDataTypeName(type);
580                                 const int               arraySize       = 3;
581
582                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName,
583                                                                                   VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize),
584                                                                                   layoutFlags[layoutFlagNdx].flags);
585
586                                 if (glu::isDataTypeMatrix(type))
587                                 {
588                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
589                                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName,
590                                                                                                   VarType(VarType(type, PRECISION_HIGH), arraySize),
591                                                                                                   layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
592                                 }
593                         }
594                 }
595         }
596
597         // ubo.single_struct
598         {
599                 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
600                 addChild(singleStructGroup);
601
602                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
603                 {
604                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
605                         singleStructGroup->addChild(modeGroup);
606
607                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
608                         {
609                                 for (int isArray = 0; isArray < 2; isArray++)
610                                 {
611                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
612                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
613
614                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
615                                                 continue; // Doesn't make sense to add this variant.
616
617                                         if (isArray)
618                                                 baseName += "_instance_array";
619
620                                         modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex",                           "", baseFlags|DECLARE_VERTEX,                                  bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
621                                         modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_fragment",                         "", baseFlags|DECLARE_FRAGMENT,                                bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
622                                         modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_both",                             "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
623                                         modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex_comp_access",       "", baseFlags|DECLARE_VERTEX,                                  bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
624                                         modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT,                            bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
625                                         modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_both_comp_access",         "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
626                                 }
627                         }
628                 }
629         }
630
631         // ubo.single_struct_array
632         {
633                 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
634                 addChild(singleStructArrayGroup);
635
636                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
637                 {
638                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
639                         singleStructArrayGroup->addChild(modeGroup);
640
641                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
642                         {
643                                 for (int isArray = 0; isArray < 2; isArray++)
644                                 {
645                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
646                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
647
648                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
649                                                 continue; // Doesn't make sense to add this variant.
650
651                                         if (isArray)
652                                                 baseName += "_instance_array";
653
654                                         modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex",                               "", baseFlags|DECLARE_VERTEX,                                         bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
655                                         modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_fragment",                     "", baseFlags|DECLARE_FRAGMENT,                                       bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
656                                         modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_both",                                 "",   baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,      bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
657                                         modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex_comp_access",   "", baseFlags|DECLARE_VERTEX,                                         bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
658                                         modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT,                                       bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
659                                         modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_both_comp_access",     "",   baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,      bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
660                                 }
661                         }
662                 }
663         }
664
665         // ubo.single_nested_struct
666         {
667                 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
668                 addChild(singleNestedStructGroup);
669
670                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
671                 {
672                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
673                         singleNestedStructGroup->addChild(modeGroup);
674
675                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
676                         {
677                                 for (int isArray = 0; isArray < 2; isArray++)
678                                 {
679                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
680                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
681
682                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
683                                                 continue; // Doesn't make sense to add this variant.
684
685                                         if (isArray)
686                                                 baseName += "_instance_array";
687
688                                         modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex",                            "", baseFlags|DECLARE_VERTEX,                                   bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
689                                         modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_fragment",                          "", baseFlags|DECLARE_FRAGMENT,                                 bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
690                                         modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_both",                                      "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
691                                         modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex_comp_access",        "", baseFlags|DECLARE_VERTEX,                                   bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
692                                         modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_fragment_comp_access",      "", baseFlags|DECLARE_FRAGMENT,                                 bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
693                                         modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_both_comp_access",          "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,  bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
694                                 }
695                         }
696                 }
697         }
698
699         // ubo.single_nested_struct_array
700         {
701                 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
702                 addChild(singleNestedStructArrayGroup);
703
704                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
705                 {
706                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
707                         singleNestedStructArrayGroup->addChild(modeGroup);
708
709                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
710                         {
711                                 for (int isArray = 0; isArray < 2; isArray++)
712                                 {
713                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
714                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
715
716                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
717                                                 continue; // Doesn't make sense to add this variant.
718
719                                         if (isArray)
720                                                 baseName += "_instance_array";
721
722                                         modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex",                               "", baseFlags|DECLARE_VERTEX,                                   bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
723                                         modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_fragment",                             "", baseFlags|DECLARE_FRAGMENT,                                 bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
724                                         modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_both",                                 "",     baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,      bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
725                                         modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex_comp_access",   "", baseFlags|DECLARE_VERTEX,                                   bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
726                                         modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT,                                 bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
727                                         modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_both_comp_access",             "",     baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT,      bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
728                                 }
729                         }
730                 }
731         }
732
733         // ubo.instance_array_basic_type
734         {
735                 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
736                 addChild(instanceArrayBasicTypeGroup);
737
738                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
739                 {
740                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
741                         instanceArrayBasicTypeGroup->addChild(layoutGroup);
742
743                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
744                         {
745                                 glu::DataType   type                    = basicTypes[basicTypeNdx];
746                                 const char*             typeName                = glu::getDataTypeName(type);
747                                 const int               numInstances    = 3;
748
749                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName,
750                                                                                   VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH),
751                                                                                   layoutFlags[layoutFlagNdx].flags, numInstances);
752
753                                 if (glu::isDataTypeMatrix(type))
754                                 {
755                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
756                                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName,
757                                                                                                   VarType(type, PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags,
758                                                                                                   numInstances);
759                                 }
760                         }
761                 }
762         }
763
764         // ubo.multi_basic_types
765         {
766                 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
767                 addChild(multiBasicTypesGroup);
768
769                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
770                 {
771                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
772                         multiBasicTypesGroup->addChild(modeGroup);
773
774                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
775                         {
776                                 for (int isArray = 0; isArray < 2; isArray++)
777                                 {
778                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
779                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
780
781                                         if (isArray)
782                                                 baseName += "_instance_array";
783
784                                         modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_vertex",                               "", baseFlags|DECLARE_VERTEX,                                   baseFlags|DECLARE_VERTEX,                                       bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
785                                         modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_fragment",                             "", baseFlags|DECLARE_FRAGMENT,                                 baseFlags|DECLARE_FRAGMENT,                                     bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
786                                         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));
787                                         modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_mixed",                                "", baseFlags|DECLARE_VERTEX,                                   baseFlags|DECLARE_FRAGMENT,                                     bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
788                                         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));
789                                         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));
790                                         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));
791                                         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));
792                                 }
793                         }
794                 }
795         }
796
797         // ubo.multi_nested_struct
798         {
799                 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
800                 addChild(multiNestedStructGroup);
801
802                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
803                 {
804                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
805                         multiNestedStructGroup->addChild(modeGroup);
806
807                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
808                         {
809                                 for (int isArray = 0; isArray < 2; isArray++)
810                                 {
811                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
812                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
813
814                                         if (isArray)
815                                                 baseName += "_instance_array";
816
817                                         modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_vertex",                               "", baseFlags|DECLARE_VERTEX,                                         baseFlags|DECLARE_VERTEX,                                       bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
818                                         modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_fragment",                     "", baseFlags|DECLARE_FRAGMENT,                                       baseFlags|DECLARE_FRAGMENT,                                     bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
819                                         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));
820                                         modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_mixed",                                "", baseFlags|DECLARE_VERTEX,                                         baseFlags|DECLARE_FRAGMENT,                                     bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
821                                         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));
822                                         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));
823                                         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));
824                                         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));
825                                 }
826                         }
827                 }
828         }
829
830         // .link_by_binding
831         {
832                 tcu::TestCaseGroup* linkByBindingGroup = new tcu::TestCaseGroup(m_testCtx, "link_by_binding", "Blocks with same name but different binding");
833                 addChild(linkByBindingGroup);
834
835                 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "single_buf_single_instance",             "", UniformBlockCase::BUFFERMODE_SINGLE, 0));
836                 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "single_buf_instance_array",              "", UniformBlockCase::BUFFERMODE_SINGLE, 2));
837                 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "per_block_buf_single_instance",  "", UniformBlockCase::BUFFERMODE_PER_BLOCK, 0));
838                 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "per_block_buf_instance_array",   "", UniformBlockCase::BUFFERMODE_PER_BLOCK, 2));
839         }
840
841         // ubo.random
842         {
843                 const deUint32  allShaders              = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS;
844                 const deUint32  allLayouts              = FEATURE_STD140_LAYOUT;
845                 const deUint32  allBasicTypes   = FEATURE_VECTORS|FEATURE_MATRICES;
846                 const deUint32  unused                  = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
847                 const deUint32  matFlags                = FEATURE_MATRIX_LAYOUT;
848                 const deUint32  allFeatures             = ~FEATURE_ARRAYS_OF_ARRAYS;
849
850                 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
851                 addChild(randomGroup);
852
853                 // Basic types.
854                 createRandomCaseGroup(randomGroup, m_testCtx, "scalar_types",   "Scalar types only, per-block buffers",                         UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused,                                                                           25, 0);
855                 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);
856                 createRandomCaseGroup(randomGroup, m_testCtx, "basic_types",    "All basic types, per-block buffers",                           UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags,                            25, 50);
857                 createRandomCaseGroup(randomGroup, m_testCtx, "basic_arrays",   "Arrays, per-block buffers",                                            UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS,     25, 50);
858
859                 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);
860                 createRandomCaseGroup(randomGroup, m_testCtx, "nested_structs",                                                 "Nested structs, per-block buffers",                                    UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS,                                                                            25, 100);
861                 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);
862                 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);
863                 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);
864
865                 createRandomCaseGroup(randomGroup, m_testCtx, "all_per_block_buffers",  "All random features, per-block buffers",       UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures,    50, 200);
866                 createRandomCaseGroup(randomGroup, m_testCtx, "all_shared_buffer",              "All random features, shared buffer",           UniformBlockCase::BUFFERMODE_SINGLE,    allFeatures,    50, 250);
867         }
868 }
869
870 } // anonymous
871
872 tcu::TestCaseGroup*     createTests     (tcu::TestContext& testCtx)
873 {
874         return new UniformBlockTests(testCtx);
875 }
876
877 } // ubo
878 } // vkt