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:
BlockBasicTypeCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const VarType & type,deUint32 layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag)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
createBlockBasicTypeCases(tcu::TestCaseGroup * group,tcu::TestContext & testCtx,const std::string & name,const VarType & type,deUint32 layoutFlags,int numInstances=0)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:
BlockSingleStructCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)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:
BlockSingleStructArrayCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)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:
BlockSingleNestedStructCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)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:
BlockSingleNestedStructArrayCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)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:
BlockMultiBasicTypesCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 flagsA,deUint32 flagsB,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)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:
BlockMultiNestedStructCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 flagsA,deUint32 flagsB,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)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:
Block2LevelStructArrayCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)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:
LinkByBindingCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,BufferMode bufferMode,int numInstances)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
createRandomCaseGroup(tcu::TestCaseGroup * parentGroup,tcu::TestContext & testCtx,const char * groupName,const char * description,UniformBlockCase::BufferMode bufferMode,deUint32 features,int numCases,deUint32 baseSeed)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
UniformBlockTests(tcu::TestContext & testCtx)350 UniformBlockTests::UniformBlockTests (tcu::TestContext& testCtx)
351 : TestCaseGroup(testCtx, "ubo", "Uniform Block tests")
352 {
353 }
354
~UniformBlockTests(void)355 UniformBlockTests::~UniformBlockTests (void)
356 {
357 }
358
init(void)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_OUT_OF_ORDER_OFFSETS; // OOO offsets handled in a dedicated case group
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 createRandomCaseGroup(randomGroup, m_testCtx, "all_out_of_order_offsets", "All random features, out of order member offsets", UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures | FEATURE_OUT_OF_ORDER_OFFSETS, 50, 300);
869 }
870 }
871
872 } // anonymous
873
createTests(tcu::TestContext & testCtx)874 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
875 {
876 return new UniformBlockTests(testCtx);
877 }
878
879 } // ubo
880 } // vkt
881