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