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 * Copyright (c) 2018 The Khronos Group Inc.
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 *//*!
23 * \file
24 * \brief Vulkan Transform Feedback Fuzz Layout Tests
25 *//*--------------------------------------------------------------------*/
26
27 #include "vktTransformFeedbackFuzzLayoutCase.hpp"
28 #include "vktTransformFeedbackRandomLayoutCase.hpp"
29
30 #include "tcuCommandLine.hpp"
31 #include "deStringUtil.hpp"
32
33 namespace vkt
34 {
35 namespace TransformFeedback
36 {
37
38 namespace
39 {
40
41 class BlockBasicTypeCase : public InterfaceBlockCase
42 {
43 public:
BlockBasicTypeCase(tcu::TestContext & testCtx,const std::string & name,const VarType & type,uint32_t layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)44 BlockBasicTypeCase(tcu::TestContext &testCtx, const std::string &name, const VarType &type, uint32_t layoutFlags,
45 int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags)
46 : InterfaceBlockCase(testCtx, name, matrixLoadFlag, testStageFlags)
47 {
48 InterfaceBlock &block = m_interface.allocBlock("Block");
49 block.addInterfaceMember(InterfaceBlockMember("var", type, 0));
50
51 VarType tempType = type;
52 while (tempType.isArrayType())
53 {
54 tempType = tempType.getElementType();
55 }
56
57 block.setFlags(layoutFlags);
58
59 if (numInstances > 0)
60 {
61 block.setArraySize(numInstances);
62 block.setInstanceName("block");
63 }
64 }
65 };
66
createBlockBasicTypeCases(tcu::TestCaseGroup & group,tcu::TestContext & testCtx,const std::string & name,const VarType & type,uint32_t layoutFlags,int numInstances=0)67 void createBlockBasicTypeCases(tcu::TestCaseGroup &group, tcu::TestContext &testCtx, const std::string &name,
68 const VarType &type, uint32_t layoutFlags, int numInstances = 0)
69 {
70 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(group.getTestContext(), name.c_str()));
71
72 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "vertex", type, layoutFlags, numInstances, LOAD_FULL_MATRIX,
73 TEST_STAGE_VERTEX));
74 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "geometry", type, layoutFlags, numInstances, LOAD_FULL_MATRIX,
75 TEST_STAGE_GEOMETRY));
76
77 group.addChild(typeGroup.release());
78 }
79
80 class BlockSingleStructCase : public InterfaceBlockCase
81 {
82 public:
BlockSingleStructCase(tcu::TestContext & testCtx,const std::string & name,uint32_t layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)83 BlockSingleStructCase(tcu::TestContext &testCtx, const std::string &name, uint32_t layoutFlags, int numInstances,
84 MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags)
85 : InterfaceBlockCase(testCtx, name, matrixLoadFlag, testStageFlags)
86 {
87 StructType &typeS = m_interface.allocStruct("S");
88 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), FIELD_UNASSIGNED); // First member is unused.
89 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_VEC3, PRECISION_HIGH), 2));
90 typeS.addMember("c", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
91
92 InterfaceBlock &block = m_interface.allocBlock("Block");
93 block.addInterfaceMember(InterfaceBlockMember("s", VarType(&typeS), 0));
94 block.setFlags(layoutFlags);
95
96 if (numInstances > 0)
97 {
98 block.setInstanceName("block");
99 block.setArraySize(numInstances);
100 }
101 }
102 };
103
104 class BlockSingleStructArrayCase : public InterfaceBlockCase
105 {
106 public:
BlockSingleStructArrayCase(tcu::TestContext & testCtx,const std::string & name,uint32_t layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)107 BlockSingleStructArrayCase(tcu::TestContext &testCtx, const std::string &name, uint32_t layoutFlags,
108 int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags)
109 : InterfaceBlockCase(testCtx, name, matrixLoadFlag, testStageFlags)
110 {
111 StructType &typeS = m_interface.allocStruct("S");
112 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), FIELD_UNASSIGNED);
113 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 2));
114 typeS.addMember("c", VarType(glu::TYPE_FLOAT, PRECISION_HIGH));
115
116 InterfaceBlock &block = m_interface.allocBlock("Block");
117 block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
118 block.addInterfaceMember(InterfaceBlockMember("s", VarType(VarType(&typeS), 2)));
119 block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
120 block.setFlags(layoutFlags);
121
122 if (numInstances > 0)
123 {
124 block.setInstanceName("block");
125 block.setArraySize(numInstances);
126 }
127 }
128 };
129
130 class BlockSingleNestedStructCase : public InterfaceBlockCase
131 {
132 public:
BlockSingleNestedStructCase(tcu::TestContext & testCtx,const std::string & name,uint32_t layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)133 BlockSingleNestedStructCase(tcu::TestContext &testCtx, const std::string &name, uint32_t layoutFlags,
134 int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags)
135 : InterfaceBlockCase(testCtx, name, matrixLoadFlag, testStageFlags)
136 {
137 StructType &typeS = m_interface.allocStruct("S");
138 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
139 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 2));
140 typeS.addMember("c", VarType(glu::TYPE_FLOAT, PRECISION_HIGH), FIELD_UNASSIGNED);
141
142 StructType &typeT = m_interface.allocStruct("T");
143 typeT.addMember("a", VarType(glu::TYPE_FLOAT_VEC3, PRECISION_MEDIUM));
144 typeT.addMember("b", VarType(&typeS));
145
146 InterfaceBlock &block = m_interface.allocBlock("Block");
147 block.addInterfaceMember(InterfaceBlockMember("s", VarType(&typeS), 0));
148 block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_UINT, PRECISION_LOW), FIELD_UNASSIGNED));
149 block.addInterfaceMember(InterfaceBlockMember("t", VarType(&typeT), 0));
150 block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_HIGH), 0));
151 block.setFlags(layoutFlags);
152
153 if (numInstances > 0)
154 {
155 block.setInstanceName("block");
156 block.setArraySize(numInstances);
157 }
158 }
159 };
160
161 class BlockSingleNestedStructArrayCase : public InterfaceBlockCase
162 {
163 public:
BlockSingleNestedStructArrayCase(tcu::TestContext & testCtx,const std::string & name,uint32_t layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)164 BlockSingleNestedStructArrayCase(tcu::TestContext &testCtx, const std::string &name, uint32_t layoutFlags,
165 int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags)
166 : InterfaceBlockCase(testCtx, name, matrixLoadFlag, testStageFlags)
167 {
168 StructType &typeS = m_interface.allocStruct("S");
169 typeS.addMember("a", VarType(VarType(glu::TYPE_FLOAT, PRECISION_HIGH), 2));
170
171 StructType &typeT = m_interface.allocStruct("T");
172 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM));
173 typeT.addMember("b", VarType(VarType(&typeS), 2));
174
175 InterfaceBlock &block = m_interface.allocBlock("Block");
176 block.addInterfaceMember(InterfaceBlockMember("s", VarType(&typeS), 0));
177 block.addInterfaceMember(
178 InterfaceBlockMember("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), FIELD_UNASSIGNED));
179 block.addInterfaceMember(InterfaceBlockMember("t", VarType(VarType(&typeT), 2), 0));
180 block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
181 block.setFlags(layoutFlags);
182
183 if (numInstances > 0)
184 {
185 block.setInstanceName("block");
186 block.setArraySize(numInstances);
187 }
188 }
189 };
190
191 class BlockMultiBasicTypesCase : public InterfaceBlockCase
192 {
193 public:
BlockMultiBasicTypesCase(tcu::TestContext & testCtx,const std::string & name,uint32_t flagsA,uint32_t flagsB,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)194 BlockMultiBasicTypesCase(tcu::TestContext &testCtx, const std::string &name, uint32_t flagsA, uint32_t flagsB,
195 int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags)
196 : InterfaceBlockCase(testCtx, name, matrixLoadFlag, testStageFlags)
197 {
198 InterfaceBlock &blockA = m_interface.allocBlock("BlockA");
199 blockA.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
200 blockA.addInterfaceMember(
201 InterfaceBlockMember("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), FIELD_UNASSIGNED));
202 blockA.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
203 blockA.setInstanceName("blockA");
204 blockA.setFlags(flagsA);
205
206 InterfaceBlock &blockB = m_interface.allocBlock("BlockB");
207 blockB.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
208 blockB.addInterfaceMember(InterfaceBlockMember("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
209 blockB.addInterfaceMember(
210 InterfaceBlockMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), FIELD_UNASSIGNED));
211 blockB.addInterfaceMember(InterfaceBlockMember("d", VarType(glu::TYPE_INT, 0)));
212 blockB.setInstanceName("blockB");
213 blockB.setFlags(flagsB);
214
215 if (numInstances > 0)
216 {
217 blockA.setArraySize(numInstances);
218 blockB.setArraySize(numInstances);
219 }
220 }
221 };
222
223 class BlockMultiNestedStructCase : public InterfaceBlockCase
224 {
225 public:
BlockMultiNestedStructCase(tcu::TestContext & testCtx,const std::string & name,uint32_t flagsA,uint32_t flagsB,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)226 BlockMultiNestedStructCase(tcu::TestContext &testCtx, const std::string &name, uint32_t flagsA, uint32_t flagsB,
227 int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags)
228 : InterfaceBlockCase(testCtx, name, matrixLoadFlag, testStageFlags)
229 {
230 StructType &typeS = m_interface.allocStruct("S");
231 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_LOW));
232 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 2));
233
234 StructType &typeT = m_interface.allocStruct("T");
235 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), FIELD_UNASSIGNED);
236 typeT.addMember("b", VarType(&typeS));
237 typeT.addMember("c", VarType(glu::TYPE_UINT_VEC3, 0));
238
239 InterfaceBlock &blockA = m_interface.allocBlock("BlockA");
240 blockA.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
241 blockA.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeS)));
242 blockA.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_UINT, PRECISION_LOW), FIELD_UNASSIGNED));
243 blockA.setInstanceName("blockA");
244 blockA.setFlags(flagsA);
245
246 InterfaceBlock &blockB = m_interface.allocBlock("BlockB");
247 blockB.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
248 blockB.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeT)));
249 blockB.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_INT, 0)));
250 blockB.setInstanceName("blockB");
251 blockB.setFlags(flagsB);
252
253 if (numInstances > 0)
254 {
255 blockA.setArraySize(numInstances);
256 blockB.setArraySize(numInstances);
257 }
258 }
259 };
260
261 class BlockVariousBuffersCase : public InterfaceBlockCase
262 {
263 public:
BlockVariousBuffersCase(tcu::TestContext & testCtx,const std::string & name,uint32_t flags,uint32_t xfbBufferA,uint32_t xfbBufferB,uint32_t xfbBufferC,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)264 BlockVariousBuffersCase(tcu::TestContext &testCtx, const std::string &name, uint32_t flags, uint32_t xfbBufferA,
265 uint32_t xfbBufferB, uint32_t xfbBufferC, int numInstances, MatrixLoadFlags matrixLoadFlag,
266 TestStageFlags testStageFlags)
267 : InterfaceBlockCase(testCtx, name, matrixLoadFlag, testStageFlags)
268 {
269 StructType &typeS = m_interface.allocStruct("S");
270 typeS.addMember("a", VarType(VarType(glu::TYPE_FLOAT, PRECISION_LOW), 3));
271 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM), 2));
272 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
273
274 StructType &typeT = m_interface.allocStruct("T");
275 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), FIELD_UNASSIGNED);
276 typeT.addMember("b", VarType(glu::TYPE_INT_VEC3, 0));
277
278 InterfaceBlock &blockA = m_interface.allocBlock("BlockA");
279 blockA.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_INT, PRECISION_HIGH)));
280 blockA.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeS)));
281 blockA.addInterfaceMember(
282 InterfaceBlockMember("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), FIELD_UNASSIGNED));
283 blockA.setInstanceName("blockA");
284 blockA.setFlags(flags);
285 blockA.setXfbBuffer(xfbBufferA);
286
287 InterfaceBlock &blockB = m_interface.allocBlock("BlockB");
288 blockB.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
289 blockB.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeT)));
290 blockB.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_INT_VEC4, 0), FIELD_UNASSIGNED));
291 blockB.addInterfaceMember(InterfaceBlockMember("d", VarType(glu::TYPE_INT, 0)));
292 blockB.setInstanceName("blockB");
293 blockB.setFlags(flags);
294 blockB.setXfbBuffer(xfbBufferB);
295
296 InterfaceBlock &blockC = m_interface.allocBlock("BlockC");
297 blockC.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_UINT, PRECISION_HIGH)));
298 blockC.addInterfaceMember(InterfaceBlockMember("b", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_HIGH)));
299 blockC.setInstanceName("blockC");
300 blockC.setFlags(flags);
301 blockC.setXfbBuffer(xfbBufferC);
302
303 if (numInstances > 0)
304 {
305 blockA.setArraySize(numInstances);
306 blockB.setArraySize(numInstances);
307 }
308 }
309 };
310
311 class Block2LevelStructArrayCase : public InterfaceBlockCase
312 {
313 public:
Block2LevelStructArrayCase(tcu::TestContext & testCtx,const std::string & name,uint32_t flags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)314 Block2LevelStructArrayCase(tcu::TestContext &testCtx, const std::string &name, uint32_t flags, int numInstances,
315 MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags)
316 : InterfaceBlockCase(testCtx, name, matrixLoadFlag, testStageFlags)
317 {
318 StructType &typeS = m_interface.allocStruct("S");
319 typeS.addMember("a", VarType(glu::TYPE_UINT_VEC3, PRECISION_HIGH), FIELD_UNASSIGNED);
320 typeS.addMember("b", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM));
321
322 InterfaceBlock &block = m_interface.allocBlock("Block");
323 block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_INT, PRECISION_MEDIUM)));
324 block.addInterfaceMember(InterfaceBlockMember("s", VarType(VarType(VarType(&typeS), 2), 2)));
325 block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM)));
326 block.setFlags(flags);
327
328 if (numInstances > 0)
329 {
330 block.setInstanceName("block");
331 block.setArraySize(numInstances);
332 }
333 }
334 };
335
createRandomCaseGroup(tcu::TestCaseGroup * parentGroup,tcu::TestContext & testCtx,const char * groupName,uint32_t numCases,TestStageFlags testStageFlags,uint32_t features)336 void createRandomCaseGroup(tcu::TestCaseGroup *parentGroup, tcu::TestContext &testCtx, const char *groupName,
337 uint32_t numCases, TestStageFlags testStageFlags, uint32_t features)
338 {
339 const uint32_t baseSeed = deStringHash(groupName) + static_cast<uint32_t>(testCtx.getCommandLine().getBaseSeed());
340 tcu::TestCaseGroup *group = new tcu::TestCaseGroup(testCtx, groupName);
341
342 parentGroup->addChild(group);
343
344 for (uint32_t ndx = 0; ndx < numCases; ndx++)
345 group->addChild(
346 new RandomInterfaceBlockCase(testCtx, de::toString(ndx), testStageFlags, features, ndx + baseSeed));
347 }
348
349 // InterfaceBlockTests
350
351 class InterfaceBlockTests : public tcu::TestCaseGroup
352 {
353 public:
354 InterfaceBlockTests(tcu::TestContext &testCtx);
355 ~InterfaceBlockTests(void);
356
357 void init(void);
358
359 private:
360 InterfaceBlockTests(const InterfaceBlockTests &other);
361 InterfaceBlockTests &operator=(const InterfaceBlockTests &other);
362 };
363
InterfaceBlockTests(tcu::TestContext & testCtx)364 InterfaceBlockTests::InterfaceBlockTests(tcu::TestContext &testCtx) : TestCaseGroup(testCtx, "fuzz")
365 {
366 }
367
~InterfaceBlockTests(void)368 InterfaceBlockTests::~InterfaceBlockTests(void)
369 {
370 }
371
init(void)372 void InterfaceBlockTests::init(void)
373 {
374 static const glu::DataType basicTypes[] = {
375 glu::TYPE_FLOAT, glu::TYPE_FLOAT_VEC2, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT_VEC4,
376 glu::TYPE_INT, glu::TYPE_INT_VEC2, glu::TYPE_INT_VEC3, glu::TYPE_INT_VEC4,
377 glu::TYPE_UINT, glu::TYPE_UINT_VEC2, glu::TYPE_UINT_VEC3, glu::TYPE_UINT_VEC4,
378 glu::TYPE_FLOAT_MAT2, glu::TYPE_FLOAT_MAT3, glu::TYPE_FLOAT_MAT4, glu::TYPE_FLOAT_MAT2X3,
379 glu::TYPE_FLOAT_MAT2X4, glu::TYPE_FLOAT_MAT3X2, glu::TYPE_FLOAT_MAT3X4, glu::TYPE_FLOAT_MAT4X2,
380 glu::TYPE_FLOAT_MAT4X3, glu::TYPE_DOUBLE, glu::TYPE_DOUBLE_VEC2, glu::TYPE_DOUBLE_VEC3,
381 glu::TYPE_DOUBLE_VEC4, glu::TYPE_DOUBLE_MAT2, glu::TYPE_DOUBLE_MAT2X3, glu::TYPE_DOUBLE_MAT2X4,
382 glu::TYPE_DOUBLE_MAT3X2, glu::TYPE_DOUBLE_MAT3, glu::TYPE_DOUBLE_MAT3X4, glu::TYPE_DOUBLE_MAT4X2,
383 glu::TYPE_DOUBLE_MAT4X3, glu::TYPE_DOUBLE_MAT4,
384 };
385
386 static const struct
387 {
388 const std::string name;
389 uint32_t flags;
390 } precisionFlags[] = {
391 // TODO remove PRECISION_LOW because both PRECISION_LOW and PRECISION_MEDIUM means relaxed precision?
392 {"lowp", PRECISION_LOW},
393 {"mediump", PRECISION_MEDIUM},
394 {"highp", PRECISION_HIGH}};
395 const uint32_t defaultFlags = LAYOUT_XFBBUFFER | LAYOUT_XFBOFFSET;
396
397 // .2_level_array
398 {
399 // 2-level basic array variable in single buffer
400 tcu::TestCaseGroup *nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array");
401 addChild(nestedArrayGroup);
402
403 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
404 {
405 const glu::DataType type = basicTypes[basicTypeNdx];
406 const char *const typeName = glu::getDataTypeName(type);
407 const int childSize = 2;
408 const int parentSize = 2;
409 const VarType childType(VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH),
410 childSize);
411 const VarType parentType(childType, parentSize);
412
413 createBlockBasicTypeCases(*nestedArrayGroup, m_testCtx, typeName, parentType, defaultFlags);
414 }
415 }
416
417 // .3_level_array
418 {
419 // 3-level basic array variable in single buffer
420 tcu::TestCaseGroup *nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "3_level_array");
421 addChild(nestedArrayGroup);
422
423 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
424 {
425 const glu::DataType type = basicTypes[basicTypeNdx];
426 const char *const typeName = glu::getDataTypeName(type);
427 const int childSize0 = 2;
428 const int childSize1 = 2;
429 const int parentSize = 2;
430 const VarType childType0(VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH),
431 childSize0);
432 const VarType childType1(childType0, childSize1);
433 const VarType parentType(childType1, parentSize);
434
435 createBlockBasicTypeCases(*nestedArrayGroup, m_testCtx, typeName, parentType, defaultFlags);
436 }
437 }
438
439 // .2_level_struct_array
440 {
441 tcu::TestCaseGroup *structArrayArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_struct_array");
442 addChild(structArrayArrayGroup);
443
444 for (int isArray = 0; isArray < 2; isArray++)
445 {
446 const std::string baseName = isArray ? "instance_array" : "std";
447 const int numInstances = isArray ? 2 : 0;
448
449 structArrayArrayGroup->addChild(new Block2LevelStructArrayCase(
450 m_testCtx, (baseName + "_vertex"), defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
451 structArrayArrayGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_geometry"),
452 defaultFlags, numInstances, LOAD_FULL_MATRIX,
453 TEST_STAGE_GEOMETRY));
454 }
455 }
456
457 // .single_basic_type
458 {
459 tcu::TestCaseGroup *singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type");
460 addChild(singleBasicTypeGroup);
461
462 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
463 {
464 glu::DataType type = basicTypes[basicTypeNdx];
465 const char *const typeName = glu::getDataTypeName(type);
466
467 if (!dataTypeSupportsPrecisionModifier(type))
468 createBlockBasicTypeCases(*singleBasicTypeGroup, m_testCtx, typeName, VarType(type, 0), defaultFlags);
469 }
470
471 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
472 {
473 de::MovePtr<tcu::TestCaseGroup> precGroup(
474 new tcu::TestCaseGroup(m_testCtx, precisionFlags[precNdx].name.c_str()));
475
476 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
477 {
478 glu::DataType type = basicTypes[basicTypeNdx];
479 const char *const typeName = glu::getDataTypeName(type);
480
481 if (dataTypeSupportsPrecisionModifier(type))
482 createBlockBasicTypeCases(*precGroup, m_testCtx, typeName,
483 VarType(type, precisionFlags[precNdx].flags), defaultFlags);
484 }
485 singleBasicTypeGroup->addChild(precGroup.release());
486 }
487 }
488
489 // .single_basic_array
490 {
491 tcu::TestCaseGroup *singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array");
492 addChild(singleBasicArrayGroup);
493
494 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
495 {
496 glu::DataType type = basicTypes[basicTypeNdx];
497 const char *const typeName = glu::getDataTypeName(type);
498 const int arraySize = 3;
499
500 createBlockBasicTypeCases(
501 *singleBasicArrayGroup, m_testCtx, typeName,
502 VarType(VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), arraySize),
503 defaultFlags);
504 }
505 }
506
507 // .single_struct
508 {
509 tcu::TestCaseGroup *singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct");
510 addChild(singleStructGroup);
511
512 for (int isArray = 0; isArray < 2; isArray++)
513 {
514 const std::string baseName = isArray ? "instance_array" : "std";
515 const int numInstances = isArray ? 3 : 0;
516
517 singleStructGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex", defaultFlags,
518 numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
519 singleStructGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_geometry", defaultFlags,
520 numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
521 }
522 }
523
524 // .single_struct_array
525 {
526 tcu::TestCaseGroup *singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array");
527 addChild(singleStructArrayGroup);
528
529 for (int isArray = 0; isArray < 2; isArray++)
530 {
531 const std::string baseName = isArray ? "instance_array" : "std";
532 const int numInstances = isArray ? 2 : 0;
533
534 singleStructArrayGroup->addChild(new BlockSingleStructArrayCase(
535 m_testCtx, baseName + "_vertex", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
536 singleStructArrayGroup->addChild(new BlockSingleStructArrayCase(
537 m_testCtx, baseName + "_geometry", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
538 }
539 }
540
541 // .single_nested_struct
542 {
543 tcu::TestCaseGroup *singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct");
544 addChild(singleNestedStructGroup);
545
546 for (int isArray = 0; isArray < 2; isArray++)
547 {
548 const std::string baseName = isArray ? "instance_array" : "std";
549 const int numInstances = isArray ? 2 : 0;
550
551 singleNestedStructGroup->addChild(new BlockSingleNestedStructCase(
552 m_testCtx, baseName + "_vertex", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
553 singleNestedStructGroup->addChild(new BlockSingleNestedStructCase(
554 m_testCtx, baseName + "_geometry", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
555 }
556 }
557
558 // .single_nested_struct_array
559 {
560 tcu::TestCaseGroup *singleNestedStructArrayGroup =
561 new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array");
562 addChild(singleNestedStructArrayGroup);
563
564 for (int isArray = 0; isArray < 2; isArray++)
565 {
566 const std::string baseName = isArray ? "instance_array" : "std";
567 const int numInstances = isArray ? 2 : 0;
568
569 singleNestedStructArrayGroup->addChild(new BlockSingleNestedStructArrayCase(
570 m_testCtx, baseName + "_vertex", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
571 singleNestedStructArrayGroup->addChild(new BlockSingleNestedStructArrayCase(
572 m_testCtx, baseName + "_geometry", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
573 }
574 }
575
576 // .instance_array_basic_type
577 {
578 tcu::TestCaseGroup *instanceArrayBasicTypeGroup =
579 new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type");
580 addChild(instanceArrayBasicTypeGroup);
581
582 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
583 {
584 glu::DataType type = basicTypes[basicTypeNdx];
585 const char *const typeName = glu::getDataTypeName(type);
586 const int numInstances = 3;
587
588 createBlockBasicTypeCases(*instanceArrayBasicTypeGroup, m_testCtx, typeName,
589 VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH),
590 defaultFlags, numInstances);
591 }
592 }
593
594 // .multi_basic_types
595 {
596 tcu::TestCaseGroup *multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types");
597 addChild(multiBasicTypesGroup);
598
599 for (int isArray = 0; isArray < 2; isArray++)
600 {
601 const std::string baseName = isArray ? "instance_array" : "std";
602 const int numInstances = isArray ? 2 : 0;
603
604 multiBasicTypesGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_vertex", defaultFlags,
605 defaultFlags, numInstances, LOAD_FULL_MATRIX,
606 TEST_STAGE_VERTEX));
607 multiBasicTypesGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_geometry", defaultFlags,
608 defaultFlags, numInstances, LOAD_FULL_MATRIX,
609 TEST_STAGE_GEOMETRY));
610 }
611 }
612
613 // .multi_nested_struct
614 {
615 tcu::TestCaseGroup *multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct");
616 addChild(multiNestedStructGroup);
617
618 for (int isArray = 0; isArray < 2; isArray++)
619 {
620 const std::string baseName = isArray ? "instance_array" : "std";
621 const int numInstances = isArray ? 2 : 0;
622
623 multiNestedStructGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_vertex",
624 defaultFlags, defaultFlags, numInstances,
625 LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
626 multiNestedStructGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_geometry",
627 defaultFlags, defaultFlags, numInstances,
628 LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
629 }
630 }
631
632 // .various_buffers
633 {
634 static const struct
635 {
636 const std::string name;
637 uint32_t bufferA;
638 uint32_t bufferB;
639 uint32_t bufferC;
640 } xfbBufferNumbers[] = {
641 {"000", 0, 0, 0},
642 {"010", 0, 1, 0},
643 {"100", 1, 0, 0},
644 {"110", 1, 1, 0},
645 };
646
647 tcu::TestCaseGroup *multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "various_buffers");
648 addChild(multiNestedStructGroup);
649
650 for (int xfbBufferNdx = 0; xfbBufferNdx < DE_LENGTH_OF_ARRAY(xfbBufferNumbers); xfbBufferNdx++)
651 {
652 const uint32_t bufferA = xfbBufferNumbers[xfbBufferNdx].bufferA;
653 const uint32_t bufferB = xfbBufferNumbers[xfbBufferNdx].bufferB;
654 const uint32_t bufferC = xfbBufferNumbers[xfbBufferNdx].bufferC;
655
656 for (int isArray = 0; isArray < 2; isArray++)
657 {
658 std::string baseName = "buffers" + xfbBufferNumbers[xfbBufferNdx].name;
659 const int numInstances = isArray ? 2 : 0;
660
661 if (isArray)
662 baseName += "_instance_array";
663
664 multiNestedStructGroup->addChild(
665 new BlockVariousBuffersCase(m_testCtx, baseName + "_vertex", defaultFlags, bufferA, bufferB,
666 bufferC, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
667 multiNestedStructGroup->addChild(
668 new BlockVariousBuffersCase(m_testCtx, baseName + "_geometry", defaultFlags, bufferA, bufferB,
669 bufferC, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
670 }
671 }
672 }
673
674 // .random
675 {
676 static const struct
677 {
678 std::string name;
679 TestStageFlags testStageFlags;
680 } stages[] = {
681 {"vertex", TEST_STAGE_VERTEX},
682 {"geometry", TEST_STAGE_GEOMETRY},
683 };
684
685 for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
686 {
687 const std::string groupName = "random_" + stages[stageNdx].name;
688 const TestStageFlags stage = stages[stageNdx].testStageFlags;
689 const uint32_t allBasicTypes = FEATURE_VECTORS | FEATURE_MATRICES | FEATURE_DOUBLES;
690 const uint32_t unused = FEATURE_UNASSIGNED_FIELDS | FEATURE_UNASSIGNED_BLOCK_MEMBERS;
691 const uint32_t disabled =
692 FEATURE_INSTANCE_ARRAYS | FEATURE_MISSING_BLOCK_MEMBERS |
693 FEATURE_OUT_OF_ORDER_OFFSETS; // OOO & missing offsets handled in a dedicated case group
694 const uint32_t allFeatures = ~disabled;
695 const uint32_t numCases = 50;
696
697 tcu::TestCaseGroup *group = new tcu::TestCaseGroup(m_testCtx, groupName.c_str());
698 addChild(group);
699
700 // Scalar types only, per-block buffers
701 createRandomCaseGroup(group, m_testCtx, "scalar_types", numCases, stage, unused);
702 // Scalar and vector types only, per-block buffers
703 createRandomCaseGroup(group, m_testCtx, "vector_types", numCases, stage, unused | FEATURE_VECTORS);
704 // All basic types, per-block buffers
705 createRandomCaseGroup(group, m_testCtx, "basic_types", numCases, stage, unused | allBasicTypes);
706 // Arrays, per-block buffers
707 createRandomCaseGroup(group, m_testCtx, "basic_arrays", numCases, stage,
708 unused | allBasicTypes | FEATURE_ARRAYS);
709
710 // Basic instance arrays, per-block buffers
711 createRandomCaseGroup(group, m_testCtx, "basic_instance_arrays", numCases, stage,
712 unused | allBasicTypes | FEATURE_INSTANCE_ARRAYS);
713 // Nested structs, per-block buffers
714 createRandomCaseGroup(group, m_testCtx, "nested_structs", numCases, stage,
715 unused | allBasicTypes | FEATURE_STRUCTS);
716 // Nested structs, arrays, per-block buffers
717 createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays", numCases, stage,
718 unused | allBasicTypes | FEATURE_STRUCTS | FEATURE_ARRAYS);
719 // Nested structs, instance arrays, per-block buffers
720 createRandomCaseGroup(group, m_testCtx, "nested_structs_instance_arrays", numCases, stage,
721 unused | allBasicTypes | FEATURE_STRUCTS | FEATURE_INSTANCE_ARRAYS);
722 // Nested structs, instance arrays, per-block buffers
723 createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays_instance_arrays", numCases, stage,
724 unused | allBasicTypes | FEATURE_STRUCTS | FEATURE_ARRAYS | FEATURE_INSTANCE_ARRAYS);
725
726 // All random features, shared buffer
727 createRandomCaseGroup(group, m_testCtx, "all_instance_array", numCases * 2, stage,
728 allFeatures | FEATURE_INSTANCE_ARRAYS);
729 // All random features, out of order member offsets
730 createRandomCaseGroup(group, m_testCtx, "all_unordered_and_instance_array", numCases * 2, stage,
731 allFeatures | FEATURE_OUT_OF_ORDER_OFFSETS | FEATURE_INSTANCE_ARRAYS);
732 // All random features, missing interface members
733 createRandomCaseGroup(group, m_testCtx, "all_missing", numCases * 2, stage,
734 allFeatures | FEATURE_MISSING_BLOCK_MEMBERS);
735 // All random features, unordered and missing members
736 createRandomCaseGroup(group, m_testCtx, "all_unordered_and_missing", numCases * 2, stage,
737 allFeatures | FEATURE_OUT_OF_ORDER_OFFSETS | FEATURE_MISSING_BLOCK_MEMBERS);
738 }
739 }
740 }
741
742 } // namespace
743
createTransformFeedbackFuzzLayoutTests(tcu::TestContext & testCtx)744 tcu::TestCaseGroup *createTransformFeedbackFuzzLayoutTests(tcu::TestContext &testCtx)
745 {
746 return new InterfaceBlockTests(testCtx);
747 }
748
749 } // namespace TransformFeedback
750 } // namespace vkt
751