1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.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 "es2fVertexArrayTest.hpp"
25#include "glsVertexArrayTests.hpp"
26
27#include "glwEnums.hpp"
28
29using namespace deqp::gls;
30
31namespace deqp
32{
33namespace gles2
34{
35namespace Functional
36{
37
38template<class T>
39static std::string typeToString (T t)
40{
41	std::stringstream strm;
42	strm << t;
43	return strm.str();
44}
45
46
47class SingleVertexArrayUsageTests : public TestCaseGroup
48{
49public:
50									SingleVertexArrayUsageTests		(Context& context);
51	virtual							~SingleVertexArrayUsageTests	(void);
52
53	virtual void					init							(void);
54
55private:
56									SingleVertexArrayUsageTests		(const SingleVertexArrayUsageTests& other);
57	SingleVertexArrayUsageTests&	operator=						(const SingleVertexArrayUsageTests& other);
58};
59
60SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context)
61	: TestCaseGroup(context, "usages", "Single vertex atribute, usage")
62{
63}
64
65SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void)
66{
67}
68
69void SingleVertexArrayUsageTests::init (void)
70{
71	// Test usage
72	Array::Usage		usages[]		= {Array::USAGE_STATIC_DRAW, Array::USAGE_STREAM_DRAW, Array::USAGE_DYNAMIC_DRAW};
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				for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
84				{
85					const int	componentCount	= 2;
86					const int	stride			= (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * componentCount : strides[strideNdx]);
87					const bool	aligned			= (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
88					MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
89																	Array::OUTPUTTYPE_VEC2,
90																	Array::STORAGE_BUFFER,
91																	usages[usageNdx],
92																	componentCount,
93																	0,
94																	stride,
95																	false,
96																	GLValue::getMinValue(inputTypes[inputTypeNdx]),
97																	GLValue::getMaxValue(inputTypes[inputTypeNdx]));
98
99					MultiVertexArrayTest::Spec spec;
100					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
101					spec.drawCount	= counts[countNdx];
102					spec.first		= 0;
103					spec.arrays.push_back(arraySpec);
104
105					std::string name = spec.getName();
106
107					if (aligned)
108						addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
109				}
110			}
111		}
112	}
113}
114
115class SingleVertexArrayStrideTests : public TestCaseGroup
116{
117public:
118									SingleVertexArrayStrideTests	(Context& context);
119	virtual							~SingleVertexArrayStrideTests	(void);
120
121	virtual void					init							(void);
122
123private:
124									SingleVertexArrayStrideTests	(const SingleVertexArrayStrideTests& other);
125	SingleVertexArrayStrideTests&	operator=						(const SingleVertexArrayStrideTests& other);
126};
127
128SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context)
129	: TestCaseGroup(context, "strides", "Single stride vertex atribute")
130{
131}
132
133SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void)
134{
135}
136
137void SingleVertexArrayStrideTests::init (void)
138{
139	// Test strides with different input types, component counts and storage, Usage(?)
140	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED};
141	Array::Storage		storages[]		= {Array::STORAGE_USER, Array::STORAGE_BUFFER};
142	int					counts[]		= {1, 256};
143	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
144
145	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
146	{
147		for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
148		{
149			for (int componentCount = 2; componentCount < 5; componentCount++)
150			{
151				for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
152				{
153					for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
154					{
155						const int	stride			= (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * componentCount : strides[strideNdx]);
156						const bool	bufferAligned	= (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
157
158						MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
159																		Array::OUTPUTTYPE_VEC4,
160																		storages[storageNdx],
161																		Array::USAGE_DYNAMIC_DRAW,
162																		componentCount,
163																		0,
164																		stride,
165																		false,
166																		GLValue::getMinValue(inputTypes[inputTypeNdx]),
167																		GLValue::getMaxValue(inputTypes[inputTypeNdx]));
168
169						MultiVertexArrayTest::Spec spec;
170						spec.primitive	= Array::PRIMITIVE_TRIANGLES;
171						spec.drawCount	= counts[countNdx];
172						spec.first		= 0;
173						spec.arrays.push_back(arraySpec);
174
175						std::string name = spec.getName();
176						if (bufferAligned)
177							addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
178					}
179				}
180			}
181		}
182	}
183}
184
185class SingleVertexArrayFirstTests : public TestCaseGroup
186{
187public:
188									SingleVertexArrayFirstTests	(Context& context);
189	virtual							~SingleVertexArrayFirstTests	(void);
190
191	virtual void					init							(void);
192
193private:
194									SingleVertexArrayFirstTests	(const SingleVertexArrayFirstTests& other);
195	SingleVertexArrayFirstTests&	operator=						(const SingleVertexArrayFirstTests& other);
196};
197
198SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context)
199	: TestCaseGroup(context, "first", "Single vertex atribute different first values")
200{
201}
202
203SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void)
204{
205}
206
207void SingleVertexArrayFirstTests::init (void)
208{
209	// Test strides with different input types, component counts and storage, Usage(?)
210	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_FIXED};
211	int					counts[]		= {5, 256};
212	int					firsts[]		= {6, 24};
213	int					offsets[]		= {1, 16, 17};
214	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
215
216	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
217	{
218		for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
219		{
220			for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
221			{
222				for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
223				{
224					for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++)
225					{
226						const int	stride	= (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
227						const bool	aligned	= ((stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0) && (offsets[offsetNdx] % Array::inputTypeSize(inputTypes[inputTypeNdx]) == 0);
228
229						MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
230																		Array::OUTPUTTYPE_VEC2,
231																		Array::STORAGE_BUFFER,
232																		Array::USAGE_DYNAMIC_DRAW,
233																		2,
234																		offsets[offsetNdx],
235																		stride,
236																		false,
237																		GLValue::getMinValue(inputTypes[inputTypeNdx]),
238																		GLValue::getMaxValue(inputTypes[inputTypeNdx]));
239
240						MultiVertexArrayTest::Spec spec;
241						spec.primitive	= Array::PRIMITIVE_TRIANGLES;
242						spec.drawCount	= counts[countNdx];
243						spec.first		= firsts[firstNdx];
244						spec.arrays.push_back(arraySpec);
245
246						std::string name = Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]);
247						if (aligned)
248							addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
249					}
250				}
251			}
252		}
253	}
254}
255
256class SingleVertexArrayOffsetTests : public TestCaseGroup
257{
258public:
259									SingleVertexArrayOffsetTests	(Context& context);
260	virtual							~SingleVertexArrayOffsetTests	(void);
261
262	virtual void					init							(void);
263
264private:
265									SingleVertexArrayOffsetTests	(const SingleVertexArrayOffsetTests& other);
266	SingleVertexArrayOffsetTests&	operator=						(const SingleVertexArrayOffsetTests& other);
267};
268
269SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context)
270	: TestCaseGroup(context, "offset", "Single vertex atribute offset element")
271{
272}
273
274SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void)
275{
276}
277
278void SingleVertexArrayOffsetTests::init (void)
279{
280	// Test strides with different input types, component counts and storage, Usage(?)
281	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_FIXED};
282	int					counts[]		= {1, 256};
283	int					offsets[]		= {1, 4, 17, 32};
284	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
285
286	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
287	{
288		for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
289		{
290			for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
291			{
292				for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
293				{
294					const int	stride	= (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
295					const bool	aligned	= ((stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0) && ((offsets[offsetNdx] % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0);
296
297					MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
298																	Array::OUTPUTTYPE_VEC2,
299																	Array::STORAGE_BUFFER,
300																	Array::USAGE_DYNAMIC_DRAW,
301																	2,
302																	offsets[offsetNdx],
303																	stride,
304																	false,
305																	GLValue::getMinValue(inputTypes[inputTypeNdx]),
306																	GLValue::getMaxValue(inputTypes[inputTypeNdx]));
307
308					MultiVertexArrayTest::Spec spec;
309					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
310					spec.drawCount	= counts[countNdx];
311					spec.first		= 0;
312					spec.arrays.push_back(arraySpec);
313
314					std::string name = spec.getName();
315					if (aligned)
316						addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
317				}
318			}
319		}
320	}
321}
322
323class SingleVertexArrayNormalizeTests : public TestCaseGroup
324{
325public:
326										SingleVertexArrayNormalizeTests		(Context& context);
327	virtual								~SingleVertexArrayNormalizeTests	(void);
328
329	virtual void						init								(void);
330
331private:
332										SingleVertexArrayNormalizeTests		(const SingleVertexArrayNormalizeTests& other);
333	SingleVertexArrayNormalizeTests&	operator=							(const SingleVertexArrayNormalizeTests& other);
334};
335
336SingleVertexArrayNormalizeTests::SingleVertexArrayNormalizeTests (Context& context)
337	: TestCaseGroup(context, "normalize", "Single normalize vertex atribute")
338{
339}
340
341SingleVertexArrayNormalizeTests::~SingleVertexArrayNormalizeTests (void)
342{
343}
344
345void SingleVertexArrayNormalizeTests::init (void)
346{
347	// Test normalization with different input types, component counts and storage
348	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED};
349	Array::Storage		storages[]		= {Array::STORAGE_USER};
350	int					counts[]		= {1, 256};
351
352	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
353	{
354		for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
355		{
356			for (int componentCount = 2; componentCount < 5; componentCount++)
357			{
358				for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
359				{
360					MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
361																	Array::OUTPUTTYPE_VEC4,
362																	storages[storageNdx],
363																	Array::USAGE_DYNAMIC_DRAW,
364																	componentCount,
365																	0,
366																	0,
367																	true,
368																	GLValue::getMinValue(inputTypes[inputTypeNdx]),
369																	GLValue::getMaxValue(inputTypes[inputTypeNdx]));
370
371					MultiVertexArrayTest::Spec spec;
372					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
373					spec.drawCount	= counts[countNdx];
374					spec.first		= 0;
375					spec.arrays.push_back(arraySpec);
376
377					std::string name = spec.getName();
378					addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
379				}
380			}
381		}
382	}
383}
384
385class SingleVertexArrayOutputTypeTests : public TestCaseGroup
386{
387public:
388											SingleVertexArrayOutputTypeTests	(Context& context);
389	virtual									~SingleVertexArrayOutputTypeTests	(void);
390
391	virtual void							init									(void);
392
393private:
394											SingleVertexArrayOutputTypeTests	(const SingleVertexArrayOutputTypeTests& other);
395	SingleVertexArrayOutputTypeTests&	operator=								(const SingleVertexArrayOutputTypeTests& other);
396};
397
398SingleVertexArrayOutputTypeTests::SingleVertexArrayOutputTypeTests (Context& context)
399	: TestCaseGroup(context, "output_types", "Single output type vertex atribute")
400{
401}
402
403SingleVertexArrayOutputTypeTests::~SingleVertexArrayOutputTypeTests (void)
404{
405}
406
407void SingleVertexArrayOutputTypeTests::init (void)
408{
409	// Test output types with different input types, component counts and storage, Usage?, Precision?, float?
410	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED};
411	Array::OutputType	outputTypes[]	= {Array::OUTPUTTYPE_VEC2, Array::OUTPUTTYPE_VEC3, Array::OUTPUTTYPE_VEC4};
412	Array::Storage		storages[]		= {Array::STORAGE_USER};
413	int					counts[]		= {1, 256};
414
415	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
416	{
417		for (int outputTypeNdx = 0; outputTypeNdx < DE_LENGTH_OF_ARRAY(outputTypes); outputTypeNdx++)
418		{
419			for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
420			{
421				for (int componentCount = 2; componentCount < 5; componentCount++)
422				{
423					for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
424					{
425						MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
426																		outputTypes[outputTypeNdx],
427																		storages[storageNdx],
428																		Array::USAGE_DYNAMIC_DRAW,
429																		componentCount,
430																		0,
431																		0,
432																		false,
433																		GLValue::getMinValue(inputTypes[inputTypeNdx]),
434																		GLValue::getMaxValue(inputTypes[inputTypeNdx]));
435
436						MultiVertexArrayTest::Spec spec;
437						spec.primitive	= Array::PRIMITIVE_TRIANGLES;
438						spec.drawCount	= counts[countNdx];
439						spec.first		= 0;
440						spec.arrays.push_back(arraySpec);
441
442						std::string name = spec.getName();
443						addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
444					}
445				}
446			}
447		}
448	}
449}
450
451class SingleVertexArrayTestGroup : public TestCaseGroup
452{
453public:
454									SingleVertexArrayTestGroup	(Context& context);
455	virtual							~SingleVertexArrayTestGroup	(void);
456
457	virtual void					init						(void);
458
459private:
460									SingleVertexArrayTestGroup	(const SingleVertexArrayTestGroup& other);
461	SingleVertexArrayTestGroup&		operator=					(const SingleVertexArrayTestGroup& other);
462};
463
464SingleVertexArrayTestGroup::SingleVertexArrayTestGroup (Context& context)
465	: TestCaseGroup(context, "single_attribute", "Single vertex atribute")
466{
467}
468
469SingleVertexArrayTestGroup::~SingleVertexArrayTestGroup (void)
470{
471}
472
473void SingleVertexArrayTestGroup::init (void)
474{
475	addChild(new SingleVertexArrayStrideTests(m_context));
476	addChild(new SingleVertexArrayNormalizeTests(m_context));
477	addChild(new SingleVertexArrayOutputTypeTests(m_context));
478	addChild(new SingleVertexArrayUsageTests(m_context));
479	addChild(new SingleVertexArrayOffsetTests(m_context));
480	addChild(new SingleVertexArrayFirstTests(m_context));
481}
482
483class MultiVertexArrayCountTests : public TestCaseGroup
484{
485public:
486									MultiVertexArrayCountTests	(Context& context);
487	virtual							~MultiVertexArrayCountTests	(void);
488
489	virtual void					init						(void);
490
491private:
492									MultiVertexArrayCountTests	(const MultiVertexArrayCountTests& other);
493	MultiVertexArrayCountTests&		operator=					(const MultiVertexArrayCountTests& other);
494
495	std::string						getTestName					(const MultiVertexArrayTest::Spec& spec);
496};
497
498MultiVertexArrayCountTests::MultiVertexArrayCountTests (Context& context)
499	: TestCaseGroup(context, "attribute_count", "Attribute counts")
500{
501}
502
503MultiVertexArrayCountTests::~MultiVertexArrayCountTests (void)
504{
505}
506
507std::string MultiVertexArrayCountTests::getTestName (const MultiVertexArrayTest::Spec& spec)
508{
509	std::stringstream name;
510	name
511		<< spec.arrays.size();
512
513	return name.str();
514}
515
516void MultiVertexArrayCountTests::init (void)
517{
518	// Test attribute counts
519	int arrayCounts[] = {2, 3, 4, 5, 6, 7, 8};
520
521	for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
522	{
523		MultiVertexArrayTest::Spec spec;
524
525		spec.primitive	= Array::PRIMITIVE_TRIANGLES;
526		spec.drawCount	= 256;
527		spec.first		= 0;
528
529		for (int arrayNdx = 0; arrayNdx < arrayCounts[arrayCountNdx]; arrayNdx++)
530		{
531			MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
532															Array::OUTPUTTYPE_VEC2,
533															Array::STORAGE_USER,
534															Array::USAGE_DYNAMIC_DRAW,
535															2,
536															0,
537															0,
538															false,
539															GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
540															GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
541
542			spec.arrays.push_back(arraySpec);
543		}
544
545		std::string name = getTestName(spec);
546		std::string desc = getTestName(spec);
547
548		addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
549	}
550}
551
552class MultiVertexArrayStorageTests : public TestCaseGroup
553{
554public:
555									MultiVertexArrayStorageTests	(Context& context);
556	virtual							~MultiVertexArrayStorageTests	(void);
557
558	virtual void					init								(void);
559
560private:
561									MultiVertexArrayStorageTests	(const MultiVertexArrayStorageTests& other);
562	MultiVertexArrayStorageTests&	operator=							(const MultiVertexArrayStorageTests& other);
563
564	void							addStorageCases 					(MultiVertexArrayTest::Spec spec, int depth);
565	std::string						getTestName							(const MultiVertexArrayTest::Spec& spec);
566};
567
568MultiVertexArrayStorageTests::MultiVertexArrayStorageTests (Context& context)
569	: TestCaseGroup(context, "storage", "Attribute storages")
570{
571}
572
573MultiVertexArrayStorageTests::~MultiVertexArrayStorageTests (void)
574{
575}
576
577std::string MultiVertexArrayStorageTests::getTestName (const MultiVertexArrayTest::Spec& spec)
578{
579	std::stringstream name;
580	name
581		<< spec.arrays.size();
582
583	for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
584	{
585		name
586			<< "_"
587			<< Array::storageToString(spec.arrays[arrayNdx].storage);
588	}
589
590	return name.str();
591}
592
593void MultiVertexArrayStorageTests::addStorageCases (MultiVertexArrayTest::Spec spec, int depth)
594{
595	if (depth == 0)
596	{
597		// Skip trivial case, used elsewhere
598		bool ok = false;
599		for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
600		{
601			if (spec.arrays[arrayNdx].storage != Array::STORAGE_USER)
602			{
603				ok = true;
604				break;
605			}
606		}
607
608		if (!ok)
609			return;
610
611		std::string name = getTestName(spec);
612		std::string desc = getTestName(spec);
613
614		addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
615		return;
616	}
617
618	Array::Storage storages[] = {Array::STORAGE_USER, Array::STORAGE_BUFFER};
619	for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
620	{
621		MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
622														Array::OUTPUTTYPE_VEC2,
623														storages[storageNdx],
624														Array::USAGE_DYNAMIC_DRAW,
625														2,
626														0,
627														0,
628														false,
629														GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
630														GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
631
632		MultiVertexArrayTest::Spec _spec = spec;
633		_spec.arrays.push_back(arraySpec);
634		addStorageCases(_spec, depth-1);
635	}
636}
637
638
639void MultiVertexArrayStorageTests::init (void)
640{
641	// Test different storages
642	int arrayCounts[] = {3};
643
644	MultiVertexArrayTest::Spec spec;
645
646	spec.primitive	= Array::PRIMITIVE_TRIANGLES;
647	spec.drawCount	= 256;
648	spec.first		= 0;
649
650	for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
651		addStorageCases(spec, arrayCounts[arrayCountNdx]);
652}
653
654class MultiVertexArrayStrideTests : public TestCaseGroup
655{
656public:
657									MultiVertexArrayStrideTests		(Context& context);
658	virtual							~MultiVertexArrayStrideTests	(void);
659
660	virtual void					init							(void);
661
662private:
663									MultiVertexArrayStrideTests		(const MultiVertexArrayStrideTests& other);
664	MultiVertexArrayStrideTests&	operator=						(const MultiVertexArrayStrideTests& other);
665
666	void							addStrideCases 					(MultiVertexArrayTest::Spec spec, int depth);
667	std::string						getTestName						(const MultiVertexArrayTest::Spec& spec);
668};
669
670MultiVertexArrayStrideTests::MultiVertexArrayStrideTests (Context& context)
671	: TestCaseGroup(context, "stride", "Strides")
672{
673}
674
675MultiVertexArrayStrideTests::~MultiVertexArrayStrideTests (void)
676{
677}
678
679std::string MultiVertexArrayStrideTests::getTestName (const MultiVertexArrayTest::Spec& spec)
680{
681	std::stringstream name;
682
683	name
684		<< spec.arrays.size();
685
686	for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
687	{
688		name
689			<< "_"
690			<< Array::inputTypeToString(spec.arrays[arrayNdx].inputType)
691			<< spec.arrays[arrayNdx].componentCount << "_"
692			<< spec.arrays[arrayNdx].stride;
693	}
694
695	return name.str();
696}
697
698void MultiVertexArrayStrideTests::init (void)
699{
700	// Test different strides, with multiple arrays, input types??
701	int arrayCounts[] = {3};
702
703	MultiVertexArrayTest::Spec spec;
704
705	spec.primitive	= Array::PRIMITIVE_TRIANGLES;
706	spec.drawCount	= 256;
707	spec.first		= 0;
708
709	for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
710		addStrideCases(spec, arrayCounts[arrayCountNdx]);
711}
712
713void MultiVertexArrayStrideTests::addStrideCases (MultiVertexArrayTest::Spec spec, int depth)
714{
715	if (depth == 0)
716	{
717		std::string name = getTestName(spec);
718		std::string desc = getTestName(spec);
719		addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
720		return;
721	}
722
723	int strides[]	= {0, -1, 17, 32};
724
725	for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
726	{
727		const int componentCount = 2;
728		MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
729														Array::OUTPUTTYPE_VEC2,
730														Array::STORAGE_USER,
731														Array::USAGE_DYNAMIC_DRAW,
732														componentCount,
733														0,
734														(strides[strideNdx] >= 0 ? strides[strideNdx] : componentCount * Array::inputTypeSize(Array::INPUTTYPE_FLOAT)),
735														false,
736														GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
737														GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
738
739		MultiVertexArrayTest::Spec _spec = spec;
740		_spec.arrays.push_back(arraySpec);
741		addStrideCases(_spec, depth-1);
742	}
743}
744
745class MultiVertexArrayOutputTests : public TestCaseGroup
746{
747public:
748										MultiVertexArrayOutputTests		(Context& context);
749	virtual								~MultiVertexArrayOutputTests	(void);
750
751	virtual void						init								(void);
752
753private:
754										MultiVertexArrayOutputTests		(const MultiVertexArrayOutputTests& other);
755	MultiVertexArrayOutputTests&	operator=							(const MultiVertexArrayOutputTests& other);
756
757	void								addInputTypeCases 					(MultiVertexArrayTest::Spec spec, int depth);
758	std::string							getTestName							(const MultiVertexArrayTest::Spec& spec);
759};
760
761MultiVertexArrayOutputTests::MultiVertexArrayOutputTests (Context& context)
762	: TestCaseGroup(context, "input_types", "input types")
763{
764}
765
766MultiVertexArrayOutputTests::~MultiVertexArrayOutputTests (void)
767{
768}
769
770std::string MultiVertexArrayOutputTests::getTestName (const MultiVertexArrayTest::Spec& spec)
771{
772	std::stringstream name;
773
774	name
775		<< spec.arrays.size();
776
777	for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
778	{
779		name
780			<< "_"
781			<< Array::inputTypeToString(spec.arrays[arrayNdx].inputType)
782			<< spec.arrays[arrayNdx].componentCount << "_"
783			<< Array::outputTypeToString(spec.arrays[arrayNdx].outputType);
784	}
785
786	return name.str();
787}
788
789void MultiVertexArrayOutputTests::init (void)
790{
791	// Test different input types, with multiple arrays
792	int arrayCounts[] = {3};
793
794	MultiVertexArrayTest::Spec spec;
795
796	spec.primitive	= Array::PRIMITIVE_TRIANGLES;
797	spec.drawCount	= 256;
798	spec.first		= 0;
799
800	for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
801		addInputTypeCases(spec, arrayCounts[arrayCountNdx]);
802}
803
804void MultiVertexArrayOutputTests::addInputTypeCases (MultiVertexArrayTest::Spec spec, int depth)
805{
806	if (depth == 0)
807	{
808		std::string name = getTestName(spec);
809		std::string desc = getTestName(spec);
810		addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
811		return;
812	}
813
814	Array::InputType inputTypes[] = {Array::INPUTTYPE_FIXED, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT};
815	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
816	{
817		MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
818														Array::OUTPUTTYPE_VEC2,
819														Array::STORAGE_USER,
820														Array::USAGE_DYNAMIC_DRAW,
821														2,
822														0,
823														0,
824														false,
825														GLValue::getMinValue(inputTypes[inputTypeNdx]),
826														GLValue::getMaxValue(inputTypes[inputTypeNdx]));
827
828		MultiVertexArrayTest::Spec _spec = spec;
829		_spec.arrays.push_back(arraySpec);
830		addInputTypeCases(_spec, depth-1);
831	}
832}
833
834class MultiVertexArrayTestGroup : public TestCaseGroup
835{
836public:
837									MultiVertexArrayTestGroup	(Context& context);
838	virtual							~MultiVertexArrayTestGroup	(void);
839
840	virtual void					init						(void);
841
842private:
843									MultiVertexArrayTestGroup	(const MultiVertexArrayTestGroup& other);
844	MultiVertexArrayTestGroup&		operator=					(const MultiVertexArrayTestGroup& other);
845};
846
847MultiVertexArrayTestGroup::MultiVertexArrayTestGroup (Context& context)
848	: TestCaseGroup(context, "multiple_attributes", "Multiple vertex atributes")
849{
850}
851
852MultiVertexArrayTestGroup::~MultiVertexArrayTestGroup (void)
853{
854}
855
856void MultiVertexArrayTestGroup::init (void)
857{
858	addChild(new MultiVertexArrayCountTests(m_context));
859	addChild(new MultiVertexArrayStorageTests(m_context));
860	addChild(new MultiVertexArrayStrideTests(m_context));
861	addChild(new MultiVertexArrayOutputTests(m_context));
862}
863
864VertexArrayTestGroup::VertexArrayTestGroup (Context& context)
865	: TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests")
866{
867}
868
869VertexArrayTestGroup::~VertexArrayTestGroup (void)
870{
871}
872
873void VertexArrayTestGroup::init (void)
874{
875	addChild(new SingleVertexArrayTestGroup(m_context));
876	addChild(new MultiVertexArrayTestGroup(m_context));
877}
878
879} // Functional
880} // gles2
881} // deqp
882
883