• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vertex array and buffer tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fVertexArrayTest.hpp"
25 #include "glsVertexArrayTests.hpp"
26 
27 #include <sstream>
28 
29 using namespace deqp::gls;
30 
31 namespace deqp
32 {
33 namespace gles3
34 {
35 namespace Functional
36 {
37 
38 class SingleVertexArrayUsageGroup : public TestCaseGroup
39 {
40 public:
41 									SingleVertexArrayUsageGroup		(Context& context, Array::Usage usage);
42 	virtual							~SingleVertexArrayUsageGroup	(void);
43 
44 	virtual void					init							(void);
45 
46 private:
47 									SingleVertexArrayUsageGroup		(const SingleVertexArrayUsageGroup& other);
48 	SingleVertexArrayUsageGroup&	operator=						(const SingleVertexArrayUsageGroup& other);
49 
50 	Array::Usage					m_usage;
51 };
52 
SingleVertexArrayUsageGroup(Context & context,Array::Usage usage)53 SingleVertexArrayUsageGroup::SingleVertexArrayUsageGroup (Context& context, Array::Usage usage)
54 	: TestCaseGroup	(context, Array::usageTypeToString(usage).c_str(), Array::usageTypeToString(usage).c_str())
55 	, m_usage		(usage)
56 {
57 }
58 
~SingleVertexArrayUsageGroup(void)59 SingleVertexArrayUsageGroup::~SingleVertexArrayUsageGroup (void)
60 {
61 }
62 
63 template<class T>
typeToString(T t)64 static std::string typeToString (T t)
65 {
66 	std::stringstream strm;
67 	strm << t;
68 	return strm.str();
69 }
70 
init(void)71 void SingleVertexArrayUsageGroup::init (void)
72 {
73 	int					counts[]		= {1, 256};
74 	int					strides[]		= {0, -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
75 	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE};
76 
77 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
78 	{
79 		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
80 		{
81 			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
82 			{
83 				const int			stride	= (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
84 				const bool			aligned	= (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
85 				const std::string	name	= "stride" + typeToString(stride) + "_" + Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_quads" + typeToString(counts[countNdx]);
86 
87 				MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
88 																Array::OUTPUTTYPE_VEC2,
89 																Array::STORAGE_BUFFER,
90 																m_usage,
91 																2,
92 																0,
93 																stride,
94 																false,
95 																GLValue::getMinValue(inputTypes[inputTypeNdx]),
96 																GLValue::getMaxValue(inputTypes[inputTypeNdx]));
97 
98 				MultiVertexArrayTest::Spec spec;
99 				spec.primitive	= Array::PRIMITIVE_TRIANGLES;
100 				spec.drawCount	= counts[countNdx];
101 				spec.first		= 0;
102 				spec.arrays.push_back(arraySpec);
103 
104 				if (aligned)
105 					addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
106 			}
107 		}
108 	}
109 }
110 
111 class SingleVertexArrayUsageTests : public TestCaseGroup
112 {
113 public:
114 									SingleVertexArrayUsageTests		(Context& context);
115 	virtual							~SingleVertexArrayUsageTests	(void);
116 
117 	virtual void					init							(void);
118 
119 private:
120 									SingleVertexArrayUsageTests		(const SingleVertexArrayUsageTests& other);
121 	SingleVertexArrayUsageTests&	operator=						(const SingleVertexArrayUsageTests& other);
122 };
123 
SingleVertexArrayUsageTests(Context & context)124 SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context)
125 	: TestCaseGroup(context, "usages", "Single vertex atribute, usage")
126 {
127 }
128 
~SingleVertexArrayUsageTests(void)129 SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void)
130 {
131 }
132 
init(void)133 void SingleVertexArrayUsageTests::init (void)
134 {
135 	// Test usage
136 	Array::Usage		usages[]		= { Array::USAGE_STATIC_DRAW, Array::USAGE_STREAM_DRAW, Array::USAGE_DYNAMIC_DRAW, Array::USAGE_STATIC_COPY, Array::USAGE_STREAM_COPY, Array::USAGE_DYNAMIC_COPY, Array::USAGE_STATIC_READ, Array::USAGE_STREAM_READ, Array::USAGE_DYNAMIC_READ };
137 	for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
138 	{
139 		addChild(new SingleVertexArrayUsageGroup(m_context, usages[usageNdx]));
140 	}
141 }
142 
143 class SingleVertexArrayStrideGroup : public TestCaseGroup
144 {
145 public:
146 									SingleVertexArrayStrideGroup	(Context& context, Array::InputType type);
147 	virtual							~SingleVertexArrayStrideGroup	(void);
148 
149 	virtual void					init							(void);
150 
151 private:
152 									SingleVertexArrayStrideGroup	(const SingleVertexArrayStrideGroup& other);
153 	SingleVertexArrayStrideGroup&	operator=						(const SingleVertexArrayStrideGroup& other);
154 
155 	Array::InputType				m_type;
156 };
157 
SingleVertexArrayStrideGroup(Context & context,Array::InputType type)158 SingleVertexArrayStrideGroup::SingleVertexArrayStrideGroup (Context& context, Array::InputType type)
159 	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
160 	, m_type		(type)
161 {
162 }
163 
~SingleVertexArrayStrideGroup(void)164 SingleVertexArrayStrideGroup::~SingleVertexArrayStrideGroup (void)
165 {
166 }
167 
init(void)168 void SingleVertexArrayStrideGroup::init (void)
169 {
170 	Array::Storage		storages[]		= {Array::STORAGE_USER, Array::STORAGE_BUFFER};
171 	int					counts[]		= {1, 256};
172 	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
173 
174 	for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
175 	{
176 		for (int componentCount = 2; componentCount < 5; componentCount++)
177 		{
178 			for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
179 			{
180 				for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
181 				{
182 					const bool	packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
183 					const int	stride			= (strides[strideNdx] < 0) ? ((packed) ? (16) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
184 					const int	alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
185 					const bool	bufferUnaligned	= (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % alignment) != 0;
186 
187 					std::string name = Array::storageToString(storages[storageNdx]) + "_stride" + typeToString(stride) + "_components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]);
188 
189 					if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4)
190 						continue;
191 
192 					MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
193 																	Array::OUTPUTTYPE_VEC4,
194 																	storages[storageNdx],
195 																	Array::USAGE_DYNAMIC_DRAW,
196 																	componentCount,
197 																	0,
198 																	stride,
199 																	false,
200 																	GLValue::getMinValue(m_type),
201 																	GLValue::getMaxValue(m_type));
202 
203 					MultiVertexArrayTest::Spec spec;
204 					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
205 					spec.drawCount	= counts[countNdx];
206 					spec.first		= 0;
207 					spec.arrays.push_back(arraySpec);
208 
209 					if (!bufferUnaligned)
210 						addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
211 				}
212 			}
213 		}
214 	}
215 }
216 
217 class SingleVertexArrayStrideTests : public TestCaseGroup
218 {
219 public:
220 									SingleVertexArrayStrideTests	(Context& context);
221 	virtual							~SingleVertexArrayStrideTests	(void);
222 
223 	virtual void					init							(void);
224 
225 private:
226 									SingleVertexArrayStrideTests	(const SingleVertexArrayStrideTests& other);
227 	SingleVertexArrayStrideTests&	operator=						(const SingleVertexArrayStrideTests& other);
228 };
229 
SingleVertexArrayStrideTests(Context & context)230 SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context)
231 	: TestCaseGroup(context, "strides", "Single stride vertex atribute")
232 {
233 }
234 
~SingleVertexArrayStrideTests(void)235 SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void)
236 {
237 }
238 
init(void)239 void SingleVertexArrayStrideTests::init (void)
240 {
241 	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED, Array::INPUTTYPE_INT_2_10_10_10 };
242 
243 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
244 	{
245 		addChild(new SingleVertexArrayStrideGroup(m_context, inputTypes[inputTypeNdx]));
246 	}
247 }
248 
249 class SingleVertexArrayFirstGroup : public TestCaseGroup
250 {
251 public:
252 									SingleVertexArrayFirstGroup	(Context& context, Array::InputType type);
253 	virtual							~SingleVertexArrayFirstGroup	(void);
254 
255 	virtual void					init							(void);
256 
257 private:
258 									SingleVertexArrayFirstGroup	(const SingleVertexArrayFirstGroup& other);
259 	SingleVertexArrayFirstGroup&	operator=						(const SingleVertexArrayFirstGroup& other);
260 	Array::InputType				m_type;
261 };
262 
SingleVertexArrayFirstGroup(Context & context,Array::InputType type)263 SingleVertexArrayFirstGroup::SingleVertexArrayFirstGroup (Context& context, Array::InputType type)
264 	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
265 	, m_type		(type)
266 {
267 }
268 
~SingleVertexArrayFirstGroup(void)269 SingleVertexArrayFirstGroup::~SingleVertexArrayFirstGroup (void)
270 {
271 }
272 
init(void)273 void SingleVertexArrayFirstGroup::init (void)
274 {
275 	int					counts[]		= {5, 256};
276 	int					firsts[]		= {6, 24};
277 	int					offsets[]		= {1, 16, 17};
278 	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
279 
280 	for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
281 	{
282 		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
283 		{
284 			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
285 			{
286 				for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++)
287 				{
288 					const bool	packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
289 					const int	componentCount	= (packed) ? (4) : (2);
290 					const int	stride			= (strides[strideNdx] < 0) ? ((packed) ? (8) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
291 					const int	alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
292 					const bool	aligned			= ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
293 					std::string name			= "first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]);
294 
295 					MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
296 																	Array::OUTPUTTYPE_VEC2,
297 																	Array::STORAGE_BUFFER,
298 																	Array::USAGE_DYNAMIC_DRAW,
299 																	componentCount,
300 																	offsets[offsetNdx],
301 																	stride,
302 																	false,
303 																	GLValue::getMinValue(m_type),
304 																	GLValue::getMaxValue(m_type));
305 
306 					MultiVertexArrayTest::Spec spec;
307 					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
308 					spec.drawCount	= counts[countNdx];
309 					spec.first		= firsts[firstNdx];
310 					spec.arrays.push_back(arraySpec);
311 
312 					if (aligned)
313 						addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
314 				}
315 			}
316 		}
317 	}
318 }
319 
320 class SingleVertexArrayFirstTests : public TestCaseGroup
321 {
322 public:
323 									SingleVertexArrayFirstTests	(Context& context);
324 	virtual							~SingleVertexArrayFirstTests	(void);
325 
326 	virtual void					init							(void);
327 
328 private:
329 									SingleVertexArrayFirstTests	(const SingleVertexArrayFirstTests& other);
330 	SingleVertexArrayFirstTests&	operator=						(const SingleVertexArrayFirstTests& other);
331 };
332 
SingleVertexArrayFirstTests(Context & context)333 SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context)
334 	: TestCaseGroup(context, "first", "Single vertex attribute, different first values to drawArrays")
335 {
336 }
337 
~SingleVertexArrayFirstTests(void)338 SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void)
339 {
340 }
341 
init(void)342 void SingleVertexArrayFirstTests::init (void)
343 {
344 	// Test offset with different input types, component counts and storage, Usage(?)
345 	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_INT_2_10_10_10 };
346 
347 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
348 	{
349 		addChild(new SingleVertexArrayFirstGroup(m_context, inputTypes[inputTypeNdx]));
350 	}
351 }
352 
353 class SingleVertexArrayOffsetGroup : public TestCaseGroup
354 {
355 public:
356 									SingleVertexArrayOffsetGroup	(Context& context, Array::InputType type);
357 	virtual							~SingleVertexArrayOffsetGroup	(void);
358 
359 	virtual void					init							(void);
360 
361 private:
362 									SingleVertexArrayOffsetGroup	(const SingleVertexArrayOffsetGroup& other);
363 	SingleVertexArrayOffsetGroup&	operator=						(const SingleVertexArrayOffsetGroup& other);
364 	Array::InputType				m_type;
365 };
366 
SingleVertexArrayOffsetGroup(Context & context,Array::InputType type)367 SingleVertexArrayOffsetGroup::SingleVertexArrayOffsetGroup (Context& context, Array::InputType type)
368 	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
369 	, m_type		(type)
370 {
371 }
372 
~SingleVertexArrayOffsetGroup(void)373 SingleVertexArrayOffsetGroup::~SingleVertexArrayOffsetGroup (void)
374 {
375 }
376 
init(void)377 void SingleVertexArrayOffsetGroup::init (void)
378 {
379 	int					counts[]		= {1, 256};
380 	int					offsets[]		= {1, 4, 17, 32};
381 	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
382 
383 	for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
384 	{
385 		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
386 		{
387 			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
388 			{
389 				const bool			packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
390 				const int			componentCount	= (packed) ? (4) : (2);
391 				const int			stride			= (strides[strideNdx] < 0 ? Array::inputTypeSize(m_type) * componentCount : strides[strideNdx]);
392 				const int			alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
393 				const bool			aligned			= ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
394 				const std::string	name			= "offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]);
395 
396 				MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
397 																Array::OUTPUTTYPE_VEC2,
398 																Array::STORAGE_BUFFER,
399 																Array::USAGE_DYNAMIC_DRAW,
400 																componentCount,
401 																offsets[offsetNdx],
402 																stride,
403 																false,
404 																GLValue::getMinValue(m_type),
405 																GLValue::getMaxValue(m_type));
406 
407 				MultiVertexArrayTest::Spec spec;
408 				spec.primitive	= Array::PRIMITIVE_TRIANGLES;
409 				spec.drawCount	= counts[countNdx];
410 				spec.first		= 0;
411 				spec.arrays.push_back(arraySpec);
412 
413 				if (aligned)
414 					addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
415 			}
416 		}
417 	}
418 }
419 
420 class SingleVertexArrayOffsetTests : public TestCaseGroup
421 {
422 public:
423 									SingleVertexArrayOffsetTests	(Context& context);
424 	virtual							~SingleVertexArrayOffsetTests	(void);
425 
426 	virtual void					init							(void);
427 
428 private:
429 									SingleVertexArrayOffsetTests	(const SingleVertexArrayOffsetTests& other);
430 	SingleVertexArrayOffsetTests&	operator=						(const SingleVertexArrayOffsetTests& other);
431 };
432 
SingleVertexArrayOffsetTests(Context & context)433 SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context)
434 	: TestCaseGroup(context, "offset", "Single vertex atribute offset element")
435 {
436 }
437 
~SingleVertexArrayOffsetTests(void)438 SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void)
439 {
440 }
441 
init(void)442 void SingleVertexArrayOffsetTests::init (void)
443 {
444 	// Test offset with different input types, component counts and storage, Usage(?)
445 	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_INT_2_10_10_10 };
446 
447 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
448 	{
449 		addChild(new SingleVertexArrayOffsetGroup(m_context, inputTypes[inputTypeNdx]));
450 	}
451 }
452 
453 class SingleVertexArrayNormalizeGroup : public TestCaseGroup
454 {
455 public:
456 										SingleVertexArrayNormalizeGroup		(Context& context, Array::InputType type);
457 	virtual								~SingleVertexArrayNormalizeGroup	(void);
458 
459 	virtual void						init								(void);
460 
461 private:
462 										SingleVertexArrayNormalizeGroup		(const SingleVertexArrayNormalizeGroup& other);
463 	SingleVertexArrayNormalizeGroup&	operator=							(const SingleVertexArrayNormalizeGroup& other);
464 	Array::InputType					m_type;
465 };
466 
SingleVertexArrayNormalizeGroup(Context & context,Array::InputType type)467 SingleVertexArrayNormalizeGroup::SingleVertexArrayNormalizeGroup (Context& context, Array::InputType type)
468 	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
469 	, m_type		(type)
470 {
471 }
472 
~SingleVertexArrayNormalizeGroup(void)473 SingleVertexArrayNormalizeGroup::~SingleVertexArrayNormalizeGroup (void)
474 {
475 }
476 
init(void)477 void SingleVertexArrayNormalizeGroup::init (void)
478 {
479 	int					counts[]		= {1, 256};
480 
481 	for (int componentCount = 2; componentCount < 5; componentCount++)
482 	{
483 		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
484 		{
485 			if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4)
486 				continue;
487 
488 			std::string name = "components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]);
489 
490 			MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
491 															Array::OUTPUTTYPE_VEC4,
492 															Array::STORAGE_USER,
493 															Array::USAGE_DYNAMIC_DRAW,
494 															componentCount,
495 															0,
496 															0,
497 															true,
498 															GLValue::getMinValue(m_type),
499 															GLValue::getMaxValue(m_type));
500 
501 			MultiVertexArrayTest::Spec spec;
502 			spec.primitive	= Array::PRIMITIVE_TRIANGLES;
503 			spec.drawCount	= counts[countNdx];
504 			spec.first		= 0;
505 			spec.arrays.push_back(arraySpec);
506 
507 			addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
508 		}
509 	}
510 }
511 
512 class SingleVertexArrayNormalizeTests : public TestCaseGroup
513 {
514 public:
515 										SingleVertexArrayNormalizeTests		(Context& context);
516 	virtual								~SingleVertexArrayNormalizeTests	(void);
517 
518 	virtual void						init								(void);
519 
520 private:
521 										SingleVertexArrayNormalizeTests		(const SingleVertexArrayNormalizeTests& other);
522 	SingleVertexArrayNormalizeTests&	operator=							(const SingleVertexArrayNormalizeTests& other);
523 };
524 
SingleVertexArrayNormalizeTests(Context & context)525 SingleVertexArrayNormalizeTests::SingleVertexArrayNormalizeTests (Context& context)
526 	: TestCaseGroup(context, "normalize", "Single normalize vertex atribute")
527 {
528 }
529 
~SingleVertexArrayNormalizeTests(void)530 SingleVertexArrayNormalizeTests::~SingleVertexArrayNormalizeTests (void)
531 {
532 }
533 
init(void)534 void SingleVertexArrayNormalizeTests::init (void)
535 {
536 	// Test normalization with different input types, component counts and storage
537 	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_UNSIGNED_INT, Array::INPUTTYPE_INT, Array::INPUTTYPE_HALF , Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10, Array::INPUTTYPE_INT_2_10_10_10 };
538 
539 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
540 	{
541 		addChild(new SingleVertexArrayNormalizeGroup(m_context, inputTypes[inputTypeNdx]));
542 	}
543 }
544 
545 class SingleVertexArrayOutputTypeGroup : public TestCaseGroup
546 {
547 public:
548 										SingleVertexArrayOutputTypeGroup	(Context& context, Array::InputType type);
549 	virtual								~SingleVertexArrayOutputTypeGroup	(void);
550 
551 	virtual void						init								(void);
552 
553 private:
554 										SingleVertexArrayOutputTypeGroup	(const SingleVertexArrayOutputTypeGroup& other);
555 	SingleVertexArrayOutputTypeGroup&	operator=							(const SingleVertexArrayOutputTypeGroup& other);
556 	Array::InputType					m_type;
557 };
558 
SingleVertexArrayOutputTypeGroup(Context & context,Array::InputType type)559 SingleVertexArrayOutputTypeGroup::SingleVertexArrayOutputTypeGroup (Context& context, Array::InputType type)
560 	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
561 	, m_type		(type)
562 {
563 }
564 
~SingleVertexArrayOutputTypeGroup(void)565 SingleVertexArrayOutputTypeGroup::~SingleVertexArrayOutputTypeGroup (void)
566 {
567 }
568 
init(void)569 void SingleVertexArrayOutputTypeGroup::init (void)
570 {
571 	Array::OutputType	outputTypes[]	= {Array::OUTPUTTYPE_VEC2, Array::OUTPUTTYPE_VEC3, Array::OUTPUTTYPE_VEC4, Array::OUTPUTTYPE_IVEC2, Array::OUTPUTTYPE_IVEC3, Array::OUTPUTTYPE_IVEC4, Array::OUTPUTTYPE_UVEC2, Array::OUTPUTTYPE_UVEC3, Array::OUTPUTTYPE_UVEC4 };
572 	Array::Storage		storages[]		= {Array::STORAGE_USER};
573 	int					counts[]		= {1, 256};
574 
575 	for (int outputTypeNdx = 0; outputTypeNdx < DE_LENGTH_OF_ARRAY(outputTypes); outputTypeNdx++)
576 	{
577 		for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
578 		{
579 			for (int componentCount = 2; componentCount < 5; componentCount++)
580 			{
581 				for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
582 				{
583 					std::string name = "components" + typeToString(componentCount) + "_" + Array::outputTypeToString(outputTypes[outputTypeNdx]) + "_quads" + typeToString(counts[countNdx]);
584 
585 					const bool inputIsSignedInteger		= m_type == Array::INPUTTYPE_INT || m_type == Array::INPUTTYPE_SHORT || m_type == Array::INPUTTYPE_BYTE;
586 					const bool inputIsUnignedInteger	= m_type == Array::INPUTTYPE_UNSIGNED_INT || m_type == Array::INPUTTYPE_UNSIGNED_SHORT || m_type == Array::INPUTTYPE_UNSIGNED_BYTE;
587 					const bool outputIsSignedInteger	= outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC2 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC3 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC4;
588 					const bool outputIsUnsignedInteger	= outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC2 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC3 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC4;
589 
590 					// If input type is float type and output type is int type skip
591 					if ((m_type == Array::INPUTTYPE_FLOAT ||  m_type == Array::INPUTTYPE_HALF || m_type == Array::INPUTTYPE_FIXED) && (outputTypes[outputTypeNdx] >= Array::OUTPUTTYPE_INT))
592 						continue;
593 
594 					if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && (outputTypes[outputTypeNdx] >= Array::OUTPUTTYPE_INT))
595 						continue;
596 
597 					if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4)
598 						continue;
599 
600 					// Loading signed data as unsigned causes undefined values and vice versa
601 					if (inputIsSignedInteger && outputIsUnsignedInteger)
602 						continue;
603 					if (inputIsUnignedInteger && outputIsSignedInteger)
604 						continue;
605 
606 					MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
607 																	outputTypes[outputTypeNdx],
608 																	storages[storageNdx],
609 																	Array::USAGE_DYNAMIC_DRAW,
610 																	componentCount,
611 																	0,
612 																	0,
613 																	false,
614 																	GLValue::getMinValue(m_type),
615 																	GLValue::getMaxValue(m_type));
616 
617 					MultiVertexArrayTest::Spec spec;
618 					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
619 					spec.drawCount	= counts[countNdx];
620 					spec.first		= 0;
621 					spec.arrays.push_back(arraySpec);
622 
623 					addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
624 				}
625 			}
626 		}
627 	}
628 }
629 
630 class SingleVertexArrayOutputTypeTests : public TestCaseGroup
631 {
632 public:
633 										SingleVertexArrayOutputTypeTests	(Context& context);
634 	virtual								~SingleVertexArrayOutputTypeTests	(void);
635 
636 	virtual void						init								(void);
637 
638 private:
639 										SingleVertexArrayOutputTypeTests	(const SingleVertexArrayOutputTypeTests& other);
640 	SingleVertexArrayOutputTypeTests&	operator=							(const SingleVertexArrayOutputTypeTests& other);
641 };
642 
SingleVertexArrayOutputTypeTests(Context & context)643 SingleVertexArrayOutputTypeTests::SingleVertexArrayOutputTypeTests (Context& context)
644 	: TestCaseGroup(context, "output_types", "Single output type vertex atribute")
645 {
646 }
647 
~SingleVertexArrayOutputTypeTests(void)648 SingleVertexArrayOutputTypeTests::~SingleVertexArrayOutputTypeTests (void)
649 {
650 }
651 
init(void)652 void SingleVertexArrayOutputTypeTests::init (void)
653 {
654 	// Test output types with different input types, component counts and storage, Usage?, Precision?, float?
655 	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_UNSIGNED_INT, Array::INPUTTYPE_INT, Array::INPUTTYPE_HALF, Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10, Array::INPUTTYPE_INT_2_10_10_10 };
656 
657 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
658 	{
659 		addChild(new SingleVertexArrayOutputTypeGroup(m_context, inputTypes[inputTypeNdx]));
660 	}
661 }
662 
663 
664 class SingleVertexArrayTestGroup : public TestCaseGroup
665 {
666 public:
667 									SingleVertexArrayTestGroup	(Context& context);
668 	virtual							~SingleVertexArrayTestGroup	(void);
669 
670 	virtual void					init						(void);
671 
672 private:
673 									SingleVertexArrayTestGroup	(const SingleVertexArrayTestGroup& other);
674 	SingleVertexArrayTestGroup&		operator=					(const SingleVertexArrayTestGroup& other);
675 };
676 
SingleVertexArrayTestGroup(Context & context)677 SingleVertexArrayTestGroup::SingleVertexArrayTestGroup (Context& context)
678 	: TestCaseGroup(context, "single_attribute", "Single vertex atribute")
679 {
680 }
681 
~SingleVertexArrayTestGroup(void)682 SingleVertexArrayTestGroup::~SingleVertexArrayTestGroup (void)
683 {
684 }
685 
init(void)686 void SingleVertexArrayTestGroup::init (void)
687 {
688 	addChild(new SingleVertexArrayStrideTests(m_context));
689 	addChild(new SingleVertexArrayNormalizeTests(m_context));
690 	addChild(new SingleVertexArrayOutputTypeTests(m_context));
691 	addChild(new SingleVertexArrayUsageTests(m_context));
692 	addChild(new SingleVertexArrayOffsetTests(m_context));
693 	addChild(new SingleVertexArrayFirstTests(m_context));
694 }
695 
696 class MultiVertexArrayCountTests : public TestCaseGroup
697 {
698 public:
699 									MultiVertexArrayCountTests	(Context& context);
700 	virtual							~MultiVertexArrayCountTests	(void);
701 
702 	virtual void					init						(void);
703 
704 private:
705 									MultiVertexArrayCountTests	(const MultiVertexArrayCountTests& other);
706 	MultiVertexArrayCountTests&		operator=					(const MultiVertexArrayCountTests& other);
707 
708 	std::string						getTestName					(const MultiVertexArrayTest::Spec& spec);
709 };
710 
MultiVertexArrayCountTests(Context & context)711 MultiVertexArrayCountTests::MultiVertexArrayCountTests (Context& context)
712 	: TestCaseGroup(context, "attribute_count", "Attribute counts")
713 {
714 }
715 
~MultiVertexArrayCountTests(void)716 MultiVertexArrayCountTests::~MultiVertexArrayCountTests (void)
717 {
718 }
719 
getTestName(const MultiVertexArrayTest::Spec & spec)720 std::string MultiVertexArrayCountTests::getTestName (const MultiVertexArrayTest::Spec& spec)
721 {
722 	std::stringstream name;
723 	name
724 		<< spec.arrays.size();
725 
726 	return name.str();
727 }
728 
init(void)729 void MultiVertexArrayCountTests::init (void)
730 {
731 	// Test attribute counts
732 	int arrayCounts[] = {2, 3, 4, 5, 6, 7, 8};
733 
734 	for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
735 	{
736 		MultiVertexArrayTest::Spec spec;
737 
738 		spec.primitive	= Array::PRIMITIVE_TRIANGLES;
739 		spec.drawCount	= 256;
740 		spec.first		= 0;
741 
742 		for (int arrayNdx = 0; arrayNdx < arrayCounts[arrayCountNdx]; arrayNdx++)
743 		{
744 			MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
745 															Array::OUTPUTTYPE_VEC2,
746 															Array::STORAGE_USER,
747 															Array::USAGE_DYNAMIC_DRAW,
748 															2,
749 															0,
750 															0,
751 															false,
752 															GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
753 															GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
754 
755 			spec.arrays.push_back(arraySpec);
756 		}
757 
758 		std::string name = getTestName(spec);
759 		std::string desc = getTestName(spec);
760 
761 		addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
762 	}
763 }
764 
765 class MultiVertexArrayStorageTests : public TestCaseGroup
766 {
767 public:
768 									MultiVertexArrayStorageTests	(Context& context);
769 	virtual							~MultiVertexArrayStorageTests	(void);
770 
771 	virtual void					init							(void);
772 
773 private:
774 									MultiVertexArrayStorageTests	(const MultiVertexArrayStorageTests& other);
775 	MultiVertexArrayStorageTests&	operator=						(const MultiVertexArrayStorageTests& other);
776 
777 	void							addStorageCases					(MultiVertexArrayTest::Spec spec, int depth);
778 	std::string						getTestName						(const MultiVertexArrayTest::Spec& spec);
779 };
780 
MultiVertexArrayStorageTests(Context & context)781 MultiVertexArrayStorageTests::MultiVertexArrayStorageTests (Context& context)
782 	: TestCaseGroup(context, "storage", "Attribute storages")
783 {
784 }
785 
~MultiVertexArrayStorageTests(void)786 MultiVertexArrayStorageTests::~MultiVertexArrayStorageTests (void)
787 {
788 }
789 
getTestName(const MultiVertexArrayTest::Spec & spec)790 std::string MultiVertexArrayStorageTests::getTestName (const MultiVertexArrayTest::Spec& spec)
791 {
792 	std::stringstream name;
793 	name
794 		<< spec.arrays.size();
795 
796 	for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
797 	{
798 		name
799 			<< "_"
800 			<< Array::storageToString(spec.arrays[arrayNdx].storage);
801 	}
802 
803 	return name.str();
804 }
805 
addStorageCases(MultiVertexArrayTest::Spec spec,int depth)806 void MultiVertexArrayStorageTests::addStorageCases (MultiVertexArrayTest::Spec spec, int depth)
807 {
808 	if (depth == 0)
809 	{
810 		// Skip trivial case, used elsewhere
811 		bool ok = false;
812 		for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
813 		{
814 			if (spec.arrays[arrayNdx].storage != Array::STORAGE_USER)
815 			{
816 				ok = true;
817 				break;
818 			}
819 		}
820 
821 		if (!ok)
822 			return;
823 
824 		std::string name = getTestName(spec);
825 		std::string desc = getTestName(spec);
826 
827 		addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
828 		return;
829 	}
830 
831 	Array::Storage storages[] = {Array::STORAGE_USER, Array::STORAGE_BUFFER};
832 	for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
833 	{
834 		MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
835 														Array::OUTPUTTYPE_VEC2,
836 														storages[storageNdx],
837 														Array::USAGE_DYNAMIC_DRAW,
838 														2,
839 														0,
840 														0,
841 														false,
842 														GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
843 														GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
844 
845 		MultiVertexArrayTest::Spec _spec = spec;
846 		_spec.arrays.push_back(arraySpec);
847 		addStorageCases(_spec, depth-1);
848 	}
849 }
850 
851 
init(void)852 void MultiVertexArrayStorageTests::init (void)
853 {
854 	// Test different storages
855 	int arrayCounts[] = {3};
856 
857 	MultiVertexArrayTest::Spec spec;
858 
859 	spec.primitive	= Array::PRIMITIVE_TRIANGLES;
860 	spec.drawCount	= 256;
861 	spec.first		= 0;
862 
863 	for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
864 		addStorageCases(spec, arrayCounts[arrayCountNdx]);
865 }
866 
867 class MultiVertexArrayStrideTests : public TestCaseGroup
868 {
869 public:
870 									MultiVertexArrayStrideTests		(Context& context);
871 	virtual							~MultiVertexArrayStrideTests	(void);
872 
873 	virtual void					init							(void);
874 
875 private:
876 									MultiVertexArrayStrideTests		(const MultiVertexArrayStrideTests& other);
877 	MultiVertexArrayStrideTests&	operator=						(const MultiVertexArrayStrideTests& other);
878 
879 	void							addStrideCases					(MultiVertexArrayTest::Spec spec, int depth);
880 	std::string						getTestName						(const MultiVertexArrayTest::Spec& spec);
881 };
882 
MultiVertexArrayStrideTests(Context & context)883 MultiVertexArrayStrideTests::MultiVertexArrayStrideTests (Context& context)
884 	: TestCaseGroup(context, "stride", "Strides")
885 {
886 }
887 
~MultiVertexArrayStrideTests(void)888 MultiVertexArrayStrideTests::~MultiVertexArrayStrideTests (void)
889 {
890 }
891 
getTestName(const MultiVertexArrayTest::Spec & spec)892 std::string MultiVertexArrayStrideTests::getTestName (const MultiVertexArrayTest::Spec& spec)
893 {
894 	std::stringstream name;
895 
896 	name
897 		<< spec.arrays.size();
898 
899 	for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
900 	{
901 		name
902 			<< "_"
903 			<< Array::inputTypeToString(spec.arrays[arrayNdx].inputType)
904 			<< spec.arrays[arrayNdx].componentCount << "_"
905 			<< spec.arrays[arrayNdx].stride;
906 	}
907 
908 	return name.str();
909 }
910 
init(void)911 void MultiVertexArrayStrideTests::init (void)
912 {
913 	// Test different strides, with multiple arrays, input types??
914 	int arrayCounts[] = {3};
915 
916 	MultiVertexArrayTest::Spec spec;
917 
918 	spec.primitive	= Array::PRIMITIVE_TRIANGLES;
919 	spec.drawCount	= 256;
920 	spec.first		= 0;
921 
922 	for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
923 		addStrideCases(spec, arrayCounts[arrayCountNdx]);
924 }
925 
addStrideCases(MultiVertexArrayTest::Spec spec,int depth)926 void MultiVertexArrayStrideTests::addStrideCases (MultiVertexArrayTest::Spec spec, int depth)
927 {
928 	if (depth == 0)
929 	{
930 		std::string name = getTestName(spec);
931 		std::string desc = getTestName(spec);
932 		addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
933 		return;
934 	}
935 
936 	int strides[]	= {0, -1, 17, 32};
937 
938 	for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
939 	{
940 		const int componentCount = 2;
941 		MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
942 														Array::OUTPUTTYPE_VEC2,
943 														Array::STORAGE_USER,
944 														Array::USAGE_DYNAMIC_DRAW,
945 														componentCount,
946 														0,
947 														(strides[strideNdx] >= 0 ? strides[strideNdx] : componentCount * Array::inputTypeSize(Array::INPUTTYPE_FLOAT)),
948 														false,
949 														GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
950 														GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
951 
952 		MultiVertexArrayTest::Spec _spec = spec;
953 		_spec.arrays.push_back(arraySpec);
954 		addStrideCases(_spec, depth-1);
955 	}
956 }
957 
958 class MultiVertexArrayOutputTests : public TestCaseGroup
959 {
960 public:
961 										MultiVertexArrayOutputTests		(Context& context);
962 	virtual								~MultiVertexArrayOutputTests	(void);
963 
964 	virtual void						init								(void);
965 
966 private:
967 										MultiVertexArrayOutputTests		(const MultiVertexArrayOutputTests& other);
968 	MultiVertexArrayOutputTests&	operator=							(const MultiVertexArrayOutputTests& other);
969 
970 	void								addInputTypeCases					(MultiVertexArrayTest::Spec spec, int depth);
971 	std::string							getTestName							(const MultiVertexArrayTest::Spec& spec);
972 };
973 
MultiVertexArrayOutputTests(Context & context)974 MultiVertexArrayOutputTests::MultiVertexArrayOutputTests (Context& context)
975 	: TestCaseGroup(context, "input_types", "input types")
976 {
977 }
978 
~MultiVertexArrayOutputTests(void)979 MultiVertexArrayOutputTests::~MultiVertexArrayOutputTests (void)
980 {
981 }
982 
getTestName(const MultiVertexArrayTest::Spec & spec)983 std::string MultiVertexArrayOutputTests::getTestName (const MultiVertexArrayTest::Spec& spec)
984 {
985 	std::stringstream name;
986 
987 	name
988 		<< spec.arrays.size();
989 
990 	for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
991 	{
992 		name
993 			<< "_"
994 			<< Array::inputTypeToString(spec.arrays[arrayNdx].inputType)
995 			<< spec.arrays[arrayNdx].componentCount << "_"
996 			<< Array::outputTypeToString(spec.arrays[arrayNdx].outputType);
997 	}
998 
999 	return name.str();
1000 }
1001 
init(void)1002 void MultiVertexArrayOutputTests::init (void)
1003 {
1004 	// Test different input types, with multiple arrays
1005 	int arrayCounts[] = {3};
1006 
1007 	MultiVertexArrayTest::Spec spec;
1008 
1009 	spec.primitive	= Array::PRIMITIVE_TRIANGLES;
1010 	spec.drawCount	= 256;
1011 	spec.first		= 0;
1012 
1013 	for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
1014 		addInputTypeCases(spec, arrayCounts[arrayCountNdx]);
1015 }
1016 
addInputTypeCases(MultiVertexArrayTest::Spec spec,int depth)1017 void MultiVertexArrayOutputTests::addInputTypeCases (MultiVertexArrayTest::Spec spec, int depth)
1018 {
1019 	if (depth == 0)
1020 	{
1021 		std::string name = getTestName(spec);
1022 		std::string desc = getTestName(spec);
1023 		addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
1024 		return;
1025 	}
1026 
1027 	Array::InputType inputTypes[] = {Array::INPUTTYPE_FIXED, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT};
1028 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
1029 	{
1030 		MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
1031 														Array::OUTPUTTYPE_VEC2,
1032 														Array::STORAGE_USER,
1033 														Array::USAGE_DYNAMIC_DRAW,
1034 														2,
1035 														0,
1036 														0,
1037 														false,
1038 														GLValue::getMinValue(inputTypes[inputTypeNdx]),
1039 														GLValue::getMaxValue(inputTypes[inputTypeNdx]));
1040 
1041 		MultiVertexArrayTest::Spec _spec = spec;
1042 		_spec.arrays.push_back(arraySpec);
1043 		addInputTypeCases(_spec, depth-1);
1044 	}
1045 }
1046 
1047 class MultiVertexArrayTestGroup : public TestCaseGroup
1048 {
1049 public:
1050 									MultiVertexArrayTestGroup	(Context& context);
1051 	virtual							~MultiVertexArrayTestGroup	(void);
1052 
1053 	virtual void					init						(void);
1054 
1055 private:
1056 									MultiVertexArrayTestGroup	(const MultiVertexArrayTestGroup& other);
1057 	MultiVertexArrayTestGroup&		operator=					(const MultiVertexArrayTestGroup& other);
1058 };
1059 
MultiVertexArrayTestGroup(Context & context)1060 MultiVertexArrayTestGroup::MultiVertexArrayTestGroup (Context& context)
1061 	: TestCaseGroup(context, "multiple_attributes", "Multiple vertex atributes")
1062 {
1063 }
1064 
~MultiVertexArrayTestGroup(void)1065 MultiVertexArrayTestGroup::~MultiVertexArrayTestGroup (void)
1066 {
1067 }
1068 
init(void)1069 void MultiVertexArrayTestGroup::init (void)
1070 {
1071 	addChild(new MultiVertexArrayCountTests(m_context));
1072 	addChild(new MultiVertexArrayStorageTests(m_context));
1073 	addChild(new MultiVertexArrayStrideTests(m_context));
1074 	addChild(new MultiVertexArrayOutputTests(m_context));
1075 }
1076 
VertexArrayTestGroup(Context & context)1077 VertexArrayTestGroup::VertexArrayTestGroup (Context& context)
1078 	: TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests")
1079 {
1080 }
1081 
~VertexArrayTestGroup(void)1082 VertexArrayTestGroup::~VertexArrayTestGroup (void)
1083 {
1084 }
1085 
init(void)1086 void VertexArrayTestGroup::init (void)
1087 {
1088 	addChild(new SingleVertexArrayTestGroup(m_context));
1089 	addChild(new MultiVertexArrayTestGroup(m_context));
1090 }
1091 
1092 } // Functional
1093 } // gles3
1094 } // deqp
1095