Home | History | Annotate | Download | only in stress
      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 unaligned access stress tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3sVertexArrayTests.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 Stress
     36 {
     37 namespace
     38 {
     39 
     40 
     41 class SingleVertexArrayUsageGroup : public TestCaseGroup
     42 {
     43 public:
     44 									SingleVertexArrayUsageGroup		(Context& context, Array::Usage usage);
     45 	virtual							~SingleVertexArrayUsageGroup	(void);
     46 
     47 	virtual void					init							(void);
     48 
     49 private:
     50 									SingleVertexArrayUsageGroup		(const SingleVertexArrayUsageGroup& other);
     51 	SingleVertexArrayUsageGroup&	operator=						(const SingleVertexArrayUsageGroup& other);
     52 
     53 	Array::Usage					m_usage;
     54 };
     55 
     56 SingleVertexArrayUsageGroup::SingleVertexArrayUsageGroup (Context& context, Array::Usage usage)
     57 	: TestCaseGroup	(context, Array::usageTypeToString(usage).c_str(), Array::usageTypeToString(usage).c_str())
     58 	, m_usage		(usage)
     59 {
     60 }
     61 
     62 SingleVertexArrayUsageGroup::~SingleVertexArrayUsageGroup (void)
     63 {
     64 }
     65 
     66 template<class T>
     67 static std::string typeToString (T t)
     68 {
     69 	std::stringstream strm;
     70 	strm << t;
     71 	return strm.str();
     72 }
     73 
     74 void SingleVertexArrayUsageGroup::init (void)
     75 {
     76 	int					counts[]		= {1, 256};
     77 	int					strides[]		= {0, -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
     78 	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE};
     79 
     80 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
     81 	{
     82 		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
     83 		{
     84 			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
     85 			{
     86 				const int			stride	= (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
     87 				const bool			aligned	= (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
     88 				const std::string	name	= "stride" + typeToString(stride) + "_" + Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_quads" + typeToString(counts[countNdx]);
     89 
     90 				MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
     91 																Array::OUTPUTTYPE_VEC2,
     92 																Array::STORAGE_BUFFER,
     93 																m_usage,
     94 																2,
     95 																0,
     96 																stride,
     97 																false,
     98 																GLValue::getMinValue(inputTypes[inputTypeNdx]),
     99 																GLValue::getMaxValue(inputTypes[inputTypeNdx]));
    100 
    101 				MultiVertexArrayTest::Spec spec;
    102 				spec.primitive	= Array::PRIMITIVE_TRIANGLES;
    103 				spec.drawCount	= counts[countNdx];
    104 				spec.first		= 0;
    105 				spec.arrays.push_back(arraySpec);
    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 class SingleVertexArrayUsageTests : public TestCaseGroup
    115 {
    116 public:
    117 									SingleVertexArrayUsageTests		(Context& context);
    118 	virtual							~SingleVertexArrayUsageTests	(void);
    119 
    120 	virtual void					init							(void);
    121 
    122 private:
    123 									SingleVertexArrayUsageTests		(const SingleVertexArrayUsageTests& other);
    124 	SingleVertexArrayUsageTests&	operator=						(const SingleVertexArrayUsageTests& other);
    125 };
    126 
    127 SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context)
    128 	: TestCaseGroup(context, "usages", "Single vertex atribute, usage")
    129 {
    130 }
    131 
    132 SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void)
    133 {
    134 }
    135 
    136 void SingleVertexArrayUsageTests::init (void)
    137 {
    138 	// Test usage
    139 	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 };
    140 	for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
    141 	{
    142 		addChild(new SingleVertexArrayUsageGroup(m_context, usages[usageNdx]));
    143 	}
    144 }
    145 
    146 class SingleVertexArrayStrideGroup : public TestCaseGroup
    147 {
    148 public:
    149 									SingleVertexArrayStrideGroup	(Context& context, Array::InputType type);
    150 	virtual							~SingleVertexArrayStrideGroup	(void);
    151 
    152 	virtual void					init							(void);
    153 
    154 private:
    155 									SingleVertexArrayStrideGroup	(const SingleVertexArrayStrideGroup& other);
    156 	SingleVertexArrayStrideGroup&	operator=						(const SingleVertexArrayStrideGroup& other);
    157 
    158 	Array::InputType				m_type;
    159 };
    160 
    161 SingleVertexArrayStrideGroup::SingleVertexArrayStrideGroup (Context& context, Array::InputType type)
    162 	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
    163 	, m_type		(type)
    164 {
    165 }
    166 
    167 SingleVertexArrayStrideGroup::~SingleVertexArrayStrideGroup (void)
    168 {
    169 }
    170 
    171 void SingleVertexArrayStrideGroup::init (void)
    172 {
    173 	Array::Storage		storages[]		= {Array::STORAGE_USER, Array::STORAGE_BUFFER};
    174 	int					counts[]		= {1, 256};
    175 	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
    176 
    177 	for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
    178 	{
    179 		for (int componentCount = 2; componentCount < 5; componentCount++)
    180 		{
    181 			for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
    182 			{
    183 				for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
    184 				{
    185 					const bool	packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
    186 					const int	stride			= (strides[strideNdx] < 0) ? ((packed) ? (16) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
    187 					const int	alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
    188 					const bool	bufferUnaligned	= (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % alignment) != 0;
    189 
    190 					std::string name = Array::storageToString(storages[storageNdx]) + "_stride" + typeToString(stride) + "_components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]);
    191 
    192 					if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4)
    193 						continue;
    194 
    195 					MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
    196 																	Array::OUTPUTTYPE_VEC4,
    197 																	storages[storageNdx],
    198 																	Array::USAGE_DYNAMIC_DRAW,
    199 																	componentCount,
    200 																	0,
    201 																	stride,
    202 																	false,
    203 																	GLValue::getMinValue(m_type),
    204 																	GLValue::getMaxValue(m_type));
    205 
    206 					MultiVertexArrayTest::Spec spec;
    207 					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
    208 					spec.drawCount	= counts[countNdx];
    209 					spec.first		= 0;
    210 					spec.arrays.push_back(arraySpec);
    211 
    212 					if (bufferUnaligned)
    213 						addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
    214 				}
    215 			}
    216 		}
    217 	}
    218 }
    219 
    220 class SingleVertexArrayStrideTests : public TestCaseGroup
    221 {
    222 public:
    223 									SingleVertexArrayStrideTests	(Context& context);
    224 	virtual							~SingleVertexArrayStrideTests	(void);
    225 
    226 	virtual void					init							(void);
    227 
    228 private:
    229 									SingleVertexArrayStrideTests	(const SingleVertexArrayStrideTests& other);
    230 	SingleVertexArrayStrideTests&	operator=						(const SingleVertexArrayStrideTests& other);
    231 };
    232 
    233 SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context)
    234 	: TestCaseGroup(context, "strides", "Single stride vertex atribute")
    235 {
    236 }
    237 
    238 SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void)
    239 {
    240 }
    241 
    242 void SingleVertexArrayStrideTests::init (void)
    243 {
    244 	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED, Array::INPUTTYPE_INT_2_10_10_10 };
    245 
    246 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
    247 	{
    248 		addChild(new SingleVertexArrayStrideGroup(m_context, inputTypes[inputTypeNdx]));
    249 	}
    250 }
    251 
    252 class SingleVertexArrayFirstGroup : public TestCaseGroup
    253 {
    254 public:
    255 									SingleVertexArrayFirstGroup	(Context& context, Array::InputType type);
    256 	virtual							~SingleVertexArrayFirstGroup	(void);
    257 
    258 	virtual void					init							(void);
    259 
    260 private:
    261 									SingleVertexArrayFirstGroup	(const SingleVertexArrayFirstGroup& other);
    262 	SingleVertexArrayFirstGroup&	operator=						(const SingleVertexArrayFirstGroup& other);
    263 	Array::InputType				m_type;
    264 };
    265 
    266 SingleVertexArrayFirstGroup::SingleVertexArrayFirstGroup (Context& context, Array::InputType type)
    267 	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
    268 	, m_type		(type)
    269 {
    270 }
    271 
    272 SingleVertexArrayFirstGroup::~SingleVertexArrayFirstGroup (void)
    273 {
    274 }
    275 
    276 void SingleVertexArrayFirstGroup::init (void)
    277 {
    278 	int					counts[]		= {5, 256};
    279 	int					firsts[]		= {6, 24};
    280 	int					offsets[]		= {1, 17};
    281 	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
    282 
    283 	for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
    284 	{
    285 		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
    286 		{
    287 			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
    288 			{
    289 				for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++)
    290 				{
    291 					const bool	packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
    292 					const int	componentCount	= (packed) ? (4) : (2);
    293 					const int	stride			= (strides[strideNdx] < 0) ? ((packed) ? (8) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
    294 					const int	alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
    295 					const bool	aligned			= ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
    296 					std::string name			= "first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]);
    297 
    298 					MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
    299 																	Array::OUTPUTTYPE_VEC2,
    300 																	Array::STORAGE_BUFFER,
    301 																	Array::USAGE_DYNAMIC_DRAW,
    302 																	componentCount,
    303 																	offsets[offsetNdx],
    304 																	stride,
    305 																	false,
    306 																	GLValue::getMinValue(m_type),
    307 																	GLValue::getMaxValue(m_type));
    308 
    309 					MultiVertexArrayTest::Spec spec;
    310 					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
    311 					spec.drawCount	= counts[countNdx];
    312 					spec.first		= firsts[firstNdx];
    313 					spec.arrays.push_back(arraySpec);
    314 
    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 SingleVertexArrayFirstTests : public TestCaseGroup
    324 {
    325 public:
    326 									SingleVertexArrayFirstTests	(Context& context);
    327 	virtual							~SingleVertexArrayFirstTests	(void);
    328 
    329 	virtual void					init							(void);
    330 
    331 private:
    332 									SingleVertexArrayFirstTests	(const SingleVertexArrayFirstTests& other);
    333 	SingleVertexArrayFirstTests&	operator=						(const SingleVertexArrayFirstTests& other);
    334 };
    335 
    336 SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context)
    337 	: TestCaseGroup(context, "first", "Single vertex attribute, different first values to drawArrays")
    338 {
    339 }
    340 
    341 SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void)
    342 {
    343 }
    344 
    345 void SingleVertexArrayFirstTests::init (void)
    346 {
    347 	// Test offset with different input types, component counts and storage, Usage(?)
    348 	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_INT_2_10_10_10 };
    349 
    350 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
    351 	{
    352 		addChild(new SingleVertexArrayFirstGroup(m_context, inputTypes[inputTypeNdx]));
    353 	}
    354 }
    355 
    356 class SingleVertexArrayOffsetGroup : public TestCaseGroup
    357 {
    358 public:
    359 									SingleVertexArrayOffsetGroup	(Context& context, Array::InputType type);
    360 	virtual							~SingleVertexArrayOffsetGroup	(void);
    361 
    362 	virtual void					init							(void);
    363 
    364 private:
    365 									SingleVertexArrayOffsetGroup	(const SingleVertexArrayOffsetGroup& other);
    366 	SingleVertexArrayOffsetGroup&	operator=						(const SingleVertexArrayOffsetGroup& other);
    367 	Array::InputType				m_type;
    368 };
    369 
    370 SingleVertexArrayOffsetGroup::SingleVertexArrayOffsetGroup (Context& context, Array::InputType type)
    371 	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
    372 	, m_type		(type)
    373 {
    374 }
    375 
    376 SingleVertexArrayOffsetGroup::~SingleVertexArrayOffsetGroup (void)
    377 {
    378 }
    379 
    380 void SingleVertexArrayOffsetGroup::init (void)
    381 {
    382 	int					counts[]		= {1, 256};
    383 	int					offsets[]		= {1, 4, 17, 32};
    384 	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
    385 
    386 	for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
    387 	{
    388 		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
    389 		{
    390 			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
    391 			{
    392 				const bool			packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
    393 				const int			componentCount	= (packed) ? (4) : (2);
    394 				const int			stride			= (strides[strideNdx] < 0 ? Array::inputTypeSize(m_type) * componentCount : strides[strideNdx]);
    395 				const int			alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
    396 				const bool			aligned			= ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
    397 				const std::string	name			= "offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(strides[strideNdx]) + "_quads" + typeToString(counts[countNdx]);
    398 
    399 				MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
    400 																Array::OUTPUTTYPE_VEC2,
    401 																Array::STORAGE_BUFFER,
    402 																Array::USAGE_DYNAMIC_DRAW,
    403 																componentCount,
    404 																offsets[offsetNdx],
    405 																stride,
    406 																false,
    407 																GLValue::getMinValue(m_type),
    408 																GLValue::getMaxValue(m_type));
    409 
    410 				MultiVertexArrayTest::Spec spec;
    411 				spec.primitive	= Array::PRIMITIVE_TRIANGLES;
    412 				spec.drawCount	= counts[countNdx];
    413 				spec.first		= 0;
    414 				spec.arrays.push_back(arraySpec);
    415 
    416 				if (!aligned)
    417 					addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
    418 			}
    419 		}
    420 	}
    421 }
    422 
    423 class SingleVertexArrayOffsetTests : public TestCaseGroup
    424 {
    425 public:
    426 									SingleVertexArrayOffsetTests	(Context& context);
    427 	virtual							~SingleVertexArrayOffsetTests	(void);
    428 
    429 	virtual void					init							(void);
    430 
    431 private:
    432 									SingleVertexArrayOffsetTests	(const SingleVertexArrayOffsetTests& other);
    433 	SingleVertexArrayOffsetTests&	operator=						(const SingleVertexArrayOffsetTests& other);
    434 };
    435 
    436 SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context)
    437 	: TestCaseGroup(context, "offset", "Single vertex atribute offset element")
    438 {
    439 }
    440 
    441 SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void)
    442 {
    443 }
    444 
    445 void SingleVertexArrayOffsetTests::init (void)
    446 {
    447 	// Test offset with different input types, component counts and storage, Usage(?)
    448 	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_INT_2_10_10_10 };
    449 
    450 	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
    451 	{
    452 		addChild(new SingleVertexArrayOffsetGroup(m_context, inputTypes[inputTypeNdx]));
    453 	}
    454 }
    455 
    456 } // anonymous
    457 
    458 VertexArrayTests::VertexArrayTests (Context& context)
    459 	: TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests")
    460 {
    461 }
    462 
    463 VertexArrayTests::~VertexArrayTests (void)
    464 {
    465 }
    466 
    467 void VertexArrayTests::init (void)
    468 {
    469 	tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "single_attribute", "Single attribute");
    470 	addChild(group);
    471 
    472 	// .single_attribute
    473 	{
    474 		group->addChild(new SingleVertexArrayStrideTests(m_context));
    475 		group->addChild(new SingleVertexArrayUsageTests(m_context));
    476 		group->addChild(new SingleVertexArrayOffsetTests(m_context));
    477 		group->addChild(new SingleVertexArrayFirstTests(m_context));
    478 	}
    479 }
    480 
    481 } // Stress
    482 } // gles3
    483 } // deqp
    484