Home | History | Annotate | Download | only in functional
      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 
     29 using namespace deqp::gls;
     30 
     31 namespace deqp
     32 {
     33 namespace gles2
     34 {
     35 namespace Functional
     36 {
     37 
     38 template<class T>
     39 static std::string typeToString (T t)
     40 {
     41 	std::stringstream strm;
     42 	strm << t;
     43 	return strm.str();
     44 }
     45 
     46 
     47 class SingleVertexArrayUsageTests : public TestCaseGroup
     48 {
     49 public:
     50 									SingleVertexArrayUsageTests		(Context& context);
     51 	virtual							~SingleVertexArrayUsageTests	(void);
     52 
     53 	virtual void					init							(void);
     54 
     55 private:
     56 									SingleVertexArrayUsageTests		(const SingleVertexArrayUsageTests& other);
     57 	SingleVertexArrayUsageTests&	operator=						(const SingleVertexArrayUsageTests& other);
     58 };
     59 
     60 SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context)
     61 	: TestCaseGroup(context, "usages", "Single vertex atribute, usage")
     62 {
     63 }
     64 
     65 SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void)
     66 {
     67 }
     68 
     69 void 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 
    115 class SingleVertexArrayStrideTests : public TestCaseGroup
    116 {
    117 public:
    118 									SingleVertexArrayStrideTests	(Context& context);
    119 	virtual							~SingleVertexArrayStrideTests	(void);
    120 
    121 	virtual void					init							(void);
    122 
    123 private:
    124 									SingleVertexArrayStrideTests	(const SingleVertexArrayStrideTests& other);
    125 	SingleVertexArrayStrideTests&	operator=						(const SingleVertexArrayStrideTests& other);
    126 };
    127 
    128 SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context)
    129 	: TestCaseGroup(context, "strides", "Single stride vertex atribute")
    130 {
    131 }
    132 
    133 SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void)
    134 {
    135 }
    136 
    137 void 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 
    185 class SingleVertexArrayFirstTests : public TestCaseGroup
    186 {
    187 public:
    188 									SingleVertexArrayFirstTests	(Context& context);
    189 	virtual							~SingleVertexArrayFirstTests	(void);
    190 
    191 	virtual void					init							(void);
    192 
    193 private:
    194 									SingleVertexArrayFirstTests	(const SingleVertexArrayFirstTests& other);
    195 	SingleVertexArrayFirstTests&	operator=						(const SingleVertexArrayFirstTests& other);
    196 };
    197 
    198 SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context)
    199 	: TestCaseGroup(context, "first", "Single vertex atribute different first values")
    200 {
    201 }
    202 
    203 SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void)
    204 {
    205 }
    206 
    207 void 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 
    256 class SingleVertexArrayOffsetTests : public TestCaseGroup
    257 {
    258 public:
    259 									SingleVertexArrayOffsetTests	(Context& context);
    260 	virtual							~SingleVertexArrayOffsetTests	(void);
    261 
    262 	virtual void					init							(void);
    263 
    264 private:
    265 									SingleVertexArrayOffsetTests	(const SingleVertexArrayOffsetTests& other);
    266 	SingleVertexArrayOffsetTests&	operator=						(const SingleVertexArrayOffsetTests& other);
    267 };
    268 
    269 SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context)
    270 	: TestCaseGroup(context, "offset", "Single vertex atribute offset element")
    271 {
    272 }
    273 
    274 SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void)
    275 {
    276 }
    277 
    278 void 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 
    323 class SingleVertexArrayNormalizeTests : public TestCaseGroup
    324 {
    325 public:
    326 										SingleVertexArrayNormalizeTests		(Context& context);
    327 	virtual								~SingleVertexArrayNormalizeTests	(void);
    328 
    329 	virtual void						init								(void);
    330 
    331 private:
    332 										SingleVertexArrayNormalizeTests		(const SingleVertexArrayNormalizeTests& other);
    333 	SingleVertexArrayNormalizeTests&	operator=							(const SingleVertexArrayNormalizeTests& other);
    334 };
    335 
    336 SingleVertexArrayNormalizeTests::SingleVertexArrayNormalizeTests (Context& context)
    337 	: TestCaseGroup(context, "normalize", "Single normalize vertex atribute")
    338 {
    339 }
    340 
    341 SingleVertexArrayNormalizeTests::~SingleVertexArrayNormalizeTests (void)
    342 {
    343 }
    344 
    345 void 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 
    385 class SingleVertexArrayOutputTypeTests : public TestCaseGroup
    386 {
    387 public:
    388 											SingleVertexArrayOutputTypeTests	(Context& context);
    389 	virtual									~SingleVertexArrayOutputTypeTests	(void);
    390 
    391 	virtual void							init									(void);
    392 
    393 private:
    394 											SingleVertexArrayOutputTypeTests	(const SingleVertexArrayOutputTypeTests& other);
    395 	SingleVertexArrayOutputTypeTests&	operator=								(const SingleVertexArrayOutputTypeTests& other);
    396 };
    397 
    398 SingleVertexArrayOutputTypeTests::SingleVertexArrayOutputTypeTests (Context& context)
    399 	: TestCaseGroup(context, "output_types", "Single output type vertex atribute")
    400 {
    401 }
    402 
    403 SingleVertexArrayOutputTypeTests::~SingleVertexArrayOutputTypeTests (void)
    404 {
    405 }
    406 
    407 void 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 
    451 class SingleVertexArrayTestGroup : public TestCaseGroup
    452 {
    453 public:
    454 									SingleVertexArrayTestGroup	(Context& context);
    455 	virtual							~SingleVertexArrayTestGroup	(void);
    456 
    457 	virtual void					init						(void);
    458 
    459 private:
    460 									SingleVertexArrayTestGroup	(const SingleVertexArrayTestGroup& other);
    461 	SingleVertexArrayTestGroup&		operator=					(const SingleVertexArrayTestGroup& other);
    462 };
    463 
    464 SingleVertexArrayTestGroup::SingleVertexArrayTestGroup (Context& context)
    465 	: TestCaseGroup(context, "single_attribute", "Single vertex atribute")
    466 {
    467 }
    468 
    469 SingleVertexArrayTestGroup::~SingleVertexArrayTestGroup (void)
    470 {
    471 }
    472 
    473 void 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 
    483 class MultiVertexArrayCountTests : public TestCaseGroup
    484 {
    485 public:
    486 									MultiVertexArrayCountTests	(Context& context);
    487 	virtual							~MultiVertexArrayCountTests	(void);
    488 
    489 	virtual void					init						(void);
    490 
    491 private:
    492 									MultiVertexArrayCountTests	(const MultiVertexArrayCountTests& other);
    493 	MultiVertexArrayCountTests&		operator=					(const MultiVertexArrayCountTests& other);
    494 
    495 	std::string						getTestName					(const MultiVertexArrayTest::Spec& spec);
    496 };
    497 
    498 MultiVertexArrayCountTests::MultiVertexArrayCountTests (Context& context)
    499 	: TestCaseGroup(context, "attribute_count", "Attribute counts")
    500 {
    501 }
    502 
    503 MultiVertexArrayCountTests::~MultiVertexArrayCountTests (void)
    504 {
    505 }
    506 
    507 std::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 
    516 void 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 
    552 class MultiVertexArrayStorageTests : public TestCaseGroup
    553 {
    554 public:
    555 									MultiVertexArrayStorageTests	(Context& context);
    556 	virtual							~MultiVertexArrayStorageTests	(void);
    557 
    558 	virtual void					init								(void);
    559 
    560 private:
    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 
    568 MultiVertexArrayStorageTests::MultiVertexArrayStorageTests (Context& context)
    569 	: TestCaseGroup(context, "storage", "Attribute storages")
    570 {
    571 }
    572 
    573 MultiVertexArrayStorageTests::~MultiVertexArrayStorageTests (void)
    574 {
    575 }
    576 
    577 std::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 
    593 void 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 
    639 void 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 
    654 class MultiVertexArrayStrideTests : public TestCaseGroup
    655 {
    656 public:
    657 									MultiVertexArrayStrideTests		(Context& context);
    658 	virtual							~MultiVertexArrayStrideTests	(void);
    659 
    660 	virtual void					init							(void);
    661 
    662 private:
    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 
    670 MultiVertexArrayStrideTests::MultiVertexArrayStrideTests (Context& context)
    671 	: TestCaseGroup(context, "stride", "Strides")
    672 {
    673 }
    674 
    675 MultiVertexArrayStrideTests::~MultiVertexArrayStrideTests (void)
    676 {
    677 }
    678 
    679 std::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 
    698 void 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 
    713 void 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 
    745 class MultiVertexArrayOutputTests : public TestCaseGroup
    746 {
    747 public:
    748 										MultiVertexArrayOutputTests		(Context& context);
    749 	virtual								~MultiVertexArrayOutputTests	(void);
    750 
    751 	virtual void						init								(void);
    752 
    753 private:
    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 
    761 MultiVertexArrayOutputTests::MultiVertexArrayOutputTests (Context& context)
    762 	: TestCaseGroup(context, "input_types", "input types")
    763 {
    764 }
    765 
    766 MultiVertexArrayOutputTests::~MultiVertexArrayOutputTests (void)
    767 {
    768 }
    769 
    770 std::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 
    789 void 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 
    804 void 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 
    834 class MultiVertexArrayTestGroup : public TestCaseGroup
    835 {
    836 public:
    837 									MultiVertexArrayTestGroup	(Context& context);
    838 	virtual							~MultiVertexArrayTestGroup	(void);
    839 
    840 	virtual void					init						(void);
    841 
    842 private:
    843 									MultiVertexArrayTestGroup	(const MultiVertexArrayTestGroup& other);
    844 	MultiVertexArrayTestGroup&		operator=					(const MultiVertexArrayTestGroup& other);
    845 };
    846 
    847 MultiVertexArrayTestGroup::MultiVertexArrayTestGroup (Context& context)
    848 	: TestCaseGroup(context, "multiple_attributes", "Multiple vertex atributes")
    849 {
    850 }
    851 
    852 MultiVertexArrayTestGroup::~MultiVertexArrayTestGroup (void)
    853 {
    854 }
    855 
    856 void 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 
    864 VertexArrayTestGroup::VertexArrayTestGroup (Context& context)
    865 	: TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests")
    866 {
    867 }
    868 
    869 VertexArrayTestGroup::~VertexArrayTestGroup (void)
    870 {
    871 }
    872 
    873 void 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