• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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