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 Drawing tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es2fDrawTests.hpp"
     25 #include "glsDrawTest.hpp"
     26 #include "tcuRenderTarget.hpp"
     27 #include "deRandom.hpp"
     28 #include "deStringUtil.hpp"
     29 #include "deUniquePtr.hpp"
     30 #include "deSTLUtil.hpp"
     31 
     32 #include "glwEnums.hpp"
     33 
     34 #include <set>
     35 
     36 namespace deqp
     37 {
     38 namespace gles2
     39 {
     40 namespace Functional
     41 {
     42 namespace
     43 {
     44 
     45 enum TestIterationType
     46 {
     47 	TYPE_DRAW_COUNT,		// !< test with 1, 5, and 25 primitives
     48 
     49 	TYPE_LAST
     50 };
     51 
     52 static void addTestIterations (gls::DrawTest* test, const gls::DrawTestSpec& baseSpec, TestIterationType type)
     53 {
     54 	gls::DrawTestSpec spec(baseSpec);
     55 
     56 	if (type == TYPE_DRAW_COUNT)
     57 	{
     58 		spec.primitiveCount = 1;
     59 		test->addIteration(spec, "draw count = 1");
     60 
     61 		spec.primitiveCount = 5;
     62 		test->addIteration(spec, "draw count = 5");
     63 
     64 		spec.primitiveCount = 25;
     65 		test->addIteration(spec, "draw count = 25");
     66 	}
     67 	else
     68 		DE_ASSERT(false);
     69 }
     70 
     71 static void genBasicSpec (gls::DrawTestSpec& spec, gls::DrawTestSpec::DrawMethod method)
     72 {
     73 	spec.apiType							= glu::ApiType::es(2,0);
     74 	spec.primitive							= gls::DrawTestSpec::PRIMITIVE_TRIANGLES;
     75 	spec.primitiveCount						= 5;
     76 	spec.drawMethod							= method;
     77 	spec.indexType							= gls::DrawTestSpec::INDEXTYPE_LAST;
     78 	spec.indexPointerOffset					= 0;
     79 	spec.indexStorage						= gls::DrawTestSpec::STORAGE_LAST;
     80 	spec.first								= 0;
     81 	spec.indexMin							= 0;
     82 	spec.indexMax							= 0;
     83 	spec.instanceCount						= 1;
     84 
     85 	spec.attribs.resize(2);
     86 
     87 	spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
     88 	spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
     89 	spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
     90 	spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
     91 	spec.attribs[0].componentCount			= 4;
     92 	spec.attribs[0].offset					= 0;
     93 	spec.attribs[0].stride					= 0;
     94 	spec.attribs[0].normalize				= false;
     95 	spec.attribs[0].instanceDivisor			= 0;
     96 	spec.attribs[0].useDefaultAttribute		= false;
     97 
     98 	spec.attribs[1].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
     99 	spec.attribs[1].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
    100 	spec.attribs[1].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
    101 	spec.attribs[1].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
    102 	spec.attribs[1].componentCount			= 2;
    103 	spec.attribs[1].offset					= 0;
    104 	spec.attribs[1].stride					= 0;
    105 	spec.attribs[1].normalize				= false;
    106 	spec.attribs[1].instanceDivisor			= 0;
    107 	spec.attribs[1].useDefaultAttribute		= false;
    108 }
    109 
    110 
    111 class AttributeGroup : public TestCaseGroup
    112 {
    113 public:
    114 									AttributeGroup	(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage);
    115 									~AttributeGroup	(void);
    116 
    117 	void							init			(void);
    118 
    119 private:
    120 	gls::DrawTestSpec::DrawMethod	m_method;
    121 	gls::DrawTestSpec::Primitive	m_primitive;
    122 	gls::DrawTestSpec::IndexType	m_indexType;
    123 	gls::DrawTestSpec::Storage		m_indexStorage;
    124 };
    125 
    126 AttributeGroup::AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage)
    127 	: TestCaseGroup		(context, name, descr)
    128 	, m_method			(drawMethod)
    129 	, m_primitive		(primitive)
    130 	, m_indexType		(indexType)
    131 	, m_indexStorage	(indexStorage)
    132 {
    133 }
    134 
    135 AttributeGroup::~AttributeGroup (void)
    136 {
    137 }
    138 
    139 void AttributeGroup::init (void)
    140 {
    141 	// Single attribute
    142 	{
    143 		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
    144 		gls::DrawTestSpec	spec;
    145 
    146 		spec.apiType							= glu::ApiType::es(2,0);
    147 		spec.primitive							= m_primitive;
    148 		spec.primitiveCount						= 0;
    149 		spec.drawMethod							= m_method;
    150 		spec.indexType							= m_indexType;
    151 		spec.indexPointerOffset					= 0;
    152 		spec.indexStorage						= m_indexStorage;
    153 		spec.first								= 0;
    154 		spec.indexMin							= 0;
    155 		spec.indexMax							= 0;
    156 		spec.instanceCount						= 1;
    157 
    158 		spec.attribs.resize(1);
    159 
    160 		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
    161 		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
    162 		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
    163 		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
    164 		spec.attribs[0].componentCount			= 2;
    165 		spec.attribs[0].offset					= 0;
    166 		spec.attribs[0].stride					= 0;
    167 		spec.attribs[0].normalize				= false;
    168 		spec.attribs[0].instanceDivisor			= 0;
    169 		spec.attribs[0].useDefaultAttribute		= false;
    170 
    171 		addTestIterations(test, spec, TYPE_DRAW_COUNT);
    172 
    173 		this->addChild(test);
    174 	}
    175 
    176 	// Multiple attribute
    177 	{
    178 		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays");
    179 		gls::DrawTestSpec	spec;
    180 
    181 		spec.apiType							= glu::ApiType::es(2,0);
    182 		spec.primitive							= m_primitive;
    183 		spec.primitiveCount						= 0;
    184 		spec.drawMethod							= m_method;
    185 		spec.indexType							= m_indexType;
    186 		spec.indexPointerOffset					= 0;
    187 		spec.indexStorage						= m_indexStorage;
    188 		spec.first								= 0;
    189 		spec.indexMin							= 0;
    190 		spec.indexMax							= 0;
    191 		spec.instanceCount						= 1;
    192 
    193 		spec.attribs.resize(2);
    194 
    195 		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
    196 		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
    197 		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
    198 		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
    199 		spec.attribs[0].componentCount			= 4;
    200 		spec.attribs[0].offset					= 0;
    201 		spec.attribs[0].stride					= 0;
    202 		spec.attribs[0].normalize				= false;
    203 		spec.attribs[0].instanceDivisor			= 0;
    204 		spec.attribs[0].useDefaultAttribute		= false;
    205 
    206 		spec.attribs[1].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
    207 		spec.attribs[1].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
    208 		spec.attribs[1].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
    209 		spec.attribs[1].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
    210 		spec.attribs[1].componentCount			= 2;
    211 		spec.attribs[1].offset					= 0;
    212 		spec.attribs[1].stride					= 0;
    213 		spec.attribs[1].normalize				= false;
    214 		spec.attribs[1].instanceDivisor			= 0;
    215 		spec.attribs[1].useDefaultAttribute		= false;
    216 
    217 		addTestIterations(test, spec, TYPE_DRAW_COUNT);
    218 
    219 		this->addChild(test);
    220 	}
    221 
    222 	// Multiple attribute, second one default.
    223 	{
    224 		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*.");
    225 		gls::DrawTestSpec	spec;
    226 
    227 		spec.apiType							= glu::ApiType::es(2,0);
    228 		spec.primitive							= m_primitive;
    229 		spec.primitiveCount						= 5;
    230 		spec.drawMethod							= m_method;
    231 		spec.indexType							= m_indexType;
    232 		spec.indexPointerOffset					= 0;
    233 		spec.indexStorage						= m_indexStorage;
    234 		spec.first								= 0;
    235 		spec.indexMin							= 0;
    236 		spec.indexMax							= 0;
    237 		spec.instanceCount						= 1;
    238 
    239 		spec.attribs.resize(2);
    240 
    241 		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
    242 		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
    243 		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
    244 		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
    245 		spec.attribs[0].componentCount			= 2;
    246 		spec.attribs[0].offset					= 0;
    247 		spec.attribs[0].stride					= 0;
    248 		spec.attribs[0].normalize				= false;
    249 		spec.attribs[0].instanceDivisor			= 0;
    250 		spec.attribs[0].useDefaultAttribute		= false;
    251 
    252 		struct IOPair
    253 		{
    254 			gls::DrawTestSpec::InputType  input;
    255 			gls::DrawTestSpec::OutputType output;
    256 			int							  componentCount;
    257 		} iopairs[] =
    258 		{
    259 			{ gls::DrawTestSpec::INPUTTYPE_FLOAT,        gls::DrawTestSpec::OUTPUTTYPE_VEC2,  4 },
    260 			{ gls::DrawTestSpec::INPUTTYPE_FLOAT,        gls::DrawTestSpec::OUTPUTTYPE_VEC4,  2 },
    261 		};
    262 
    263 		for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
    264 		{
    265 			const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);
    266 
    267 			spec.attribs[1].inputType			= iopairs[ioNdx].input;
    268 			spec.attribs[1].outputType			= iopairs[ioNdx].output;
    269 			spec.attribs[1].storage				= gls::DrawTestSpec::STORAGE_BUFFER;
    270 			spec.attribs[1].usage				= gls::DrawTestSpec::USAGE_STATIC_DRAW;
    271 			spec.attribs[1].componentCount		= iopairs[ioNdx].componentCount;
    272 			spec.attribs[1].offset				= 0;
    273 			spec.attribs[1].stride				= 0;
    274 			spec.attribs[1].normalize			= false;
    275 			spec.attribs[1].instanceDivisor		= 0;
    276 			spec.attribs[1].useDefaultAttribute	= true;
    277 
    278 			test->addIteration(spec, desc.c_str());
    279 		}
    280 
    281 		this->addChild(test);
    282 	}
    283 }
    284 
    285 class IndexGroup : public TestCaseGroup
    286 {
    287 public:
    288 									IndexGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
    289 									~IndexGroup		(void);
    290 
    291 	void							init			(void);
    292 
    293 private:
    294 	gls::DrawTestSpec::DrawMethod	m_method;
    295 };
    296 
    297 IndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
    298 	: TestCaseGroup		(context, name, descr)
    299 	, m_method			(drawMethod)
    300 {
    301 }
    302 
    303 IndexGroup::~IndexGroup (void)
    304 {
    305 }
    306 
    307 void IndexGroup::init (void)
    308 {
    309 	struct IndexTest
    310 	{
    311 		gls::DrawTestSpec::Storage		storage;
    312 		gls::DrawTestSpec::IndexType	type;
    313 		bool							aligned;
    314 		int								offsets[3];
    315 	};
    316 
    317 	const IndexTest tests[] =
    318 	{
    319 		{ gls::DrawTestSpec::STORAGE_USER,		gls::DrawTestSpec::INDEXTYPE_BYTE,	true,	{ 0, 1, -1 } },
    320 		{ gls::DrawTestSpec::STORAGE_USER,		gls::DrawTestSpec::INDEXTYPE_SHORT,	true,	{ 0, 2, -1 } },
    321 
    322 		{ gls::DrawTestSpec::STORAGE_USER,		gls::DrawTestSpec::INDEXTYPE_SHORT,	false,	{ 1, 3, -1 } },
    323 
    324 		{ gls::DrawTestSpec::STORAGE_BUFFER,	gls::DrawTestSpec::INDEXTYPE_BYTE,	true,	{ 0, 1, -1 } },
    325 		{ gls::DrawTestSpec::STORAGE_BUFFER,	gls::DrawTestSpec::INDEXTYPE_SHORT,	true,	{ 0, 2, -1 } },
    326 
    327 		{ gls::DrawTestSpec::STORAGE_BUFFER,	gls::DrawTestSpec::INDEXTYPE_SHORT,	false,	{ 1, 3, -1 } },
    328 	};
    329 
    330 	gls::DrawTestSpec spec;
    331 
    332 	tcu::TestCaseGroup* userPtrGroup			= new tcu::TestCaseGroup(m_testCtx, "user_ptr", "user pointer");
    333 	tcu::TestCaseGroup* unalignedUserPtrGroup	= new tcu::TestCaseGroup(m_testCtx, "unaligned_user_ptr", "unaligned user pointer");
    334 	tcu::TestCaseGroup* bufferGroup				= new tcu::TestCaseGroup(m_testCtx, "buffer", "buffer");
    335 	tcu::TestCaseGroup* unalignedBufferGroup	= new tcu::TestCaseGroup(m_testCtx, "unaligned_buffer", "unaligned buffer");
    336 
    337 	genBasicSpec(spec, m_method);
    338 
    339 	this->addChild(userPtrGroup);
    340 	this->addChild(unalignedUserPtrGroup);
    341 	this->addChild(bufferGroup);
    342 	this->addChild(unalignedBufferGroup);
    343 
    344 	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
    345 	{
    346 		const IndexTest&				indexTest	= tests[testNdx];
    347 		tcu::TestCaseGroup*				group		= (indexTest.storage == gls::DrawTestSpec::STORAGE_USER) ? ((indexTest.aligned) ? (userPtrGroup) : (unalignedUserPtrGroup)) : ((indexTest.aligned) ? (bufferGroup) : (unalignedBufferGroup));
    348 
    349 		const std::string				name		= std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
    350 		const std::string				desc		= std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type) + " in " + gls::DrawTestSpec::storageToString(indexTest.storage);
    351 		de::MovePtr<gls::DrawTest>		test		(new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str()));
    352 
    353 		spec.indexType			= indexTest.type;
    354 		spec.indexStorage		= indexTest.storage;
    355 
    356 		for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
    357 		{
    358 			const std::string iterationDesc = std::string("offset ") + de::toString(indexTest.offsets[iterationNdx]);
    359 			spec.indexPointerOffset	= indexTest.offsets[iterationNdx];
    360 			test->addIteration(spec, iterationDesc.c_str());
    361 		}
    362 
    363 		if (spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET &&
    364 			spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
    365 			group->addChild(test.release());
    366 	}
    367 }
    368 
    369 
    370 class FirstGroup : public TestCaseGroup
    371 {
    372 public:
    373 									FirstGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
    374 									~FirstGroup		(void);
    375 
    376 	void							init			(void);
    377 
    378 private:
    379 	gls::DrawTestSpec::DrawMethod	m_method;
    380 };
    381 
    382 FirstGroup::FirstGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
    383 	: TestCaseGroup		(context, name, descr)
    384 	, m_method			(drawMethod)
    385 {
    386 }
    387 
    388 FirstGroup::~FirstGroup (void)
    389 {
    390 }
    391 
    392 void FirstGroup::init (void)
    393 {
    394 	const int firsts[] =
    395 	{
    396 		0, 1, 17
    397 	};
    398 
    399 	gls::DrawTestSpec spec;
    400 	genBasicSpec(spec, m_method);
    401 
    402 	for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); ++firstNdx)
    403 	{
    404 		const std::string	name = std::string("first_") + de::toString(firsts[firstNdx]);
    405 		const std::string	desc = std::string("first ") + de::toString(firsts[firstNdx]);
    406 		gls::DrawTest*		test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
    407 
    408 		spec.first = firsts[firstNdx];
    409 
    410 		addTestIterations(test, spec, TYPE_DRAW_COUNT);
    411 
    412 		this->addChild(test);
    413 	}
    414 }
    415 
    416 class MethodGroup : public TestCaseGroup
    417 {
    418 public:
    419 									MethodGroup			(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
    420 									~MethodGroup		(void);
    421 
    422 	void							init				(void);
    423 
    424 private:
    425 	gls::DrawTestSpec::DrawMethod	m_method;
    426 };
    427 
    428 MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
    429 	: TestCaseGroup		(context, name, descr)
    430 	, m_method			(drawMethod)
    431 {
    432 }
    433 
    434 MethodGroup::~MethodGroup (void)
    435 {
    436 }
    437 
    438 void MethodGroup::init (void)
    439 {
    440 	const bool indexed		= (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED);
    441 	const bool hasFirst		= (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED);
    442 
    443 	const gls::DrawTestSpec::Primitive primitive[] =
    444 	{
    445 		gls::DrawTestSpec::PRIMITIVE_POINTS,
    446 		gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
    447 		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
    448 		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
    449 		gls::DrawTestSpec::PRIMITIVE_LINES,
    450 		gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
    451 		gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
    452 	};
    453 
    454 	if (hasFirst)
    455 	{
    456 		// First-tests
    457 		this->addChild(new FirstGroup(m_context, "first", "First tests", m_method));
    458 	}
    459 
    460 	if (indexed)
    461 	{
    462 		// Index-tests
    463 		if (m_method != gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED)
    464 			this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
    465 	}
    466 
    467 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
    468 	{
    469 		const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
    470 		const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
    471 
    472 		this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
    473 	}
    474 }
    475 
    476 class RandomGroup : public TestCaseGroup
    477 {
    478 public:
    479 									RandomGroup		(Context& context, const char* name, const char* descr);
    480 									~RandomGroup	(void);
    481 
    482 	void							init			(void);
    483 };
    484 
    485 template <int SIZE>
    486 struct UniformWeightArray
    487 {
    488 	float weights[SIZE];
    489 
    490 	UniformWeightArray (void)
    491 	{
    492 		for (int i=0; i<SIZE; ++i)
    493 			weights[i] = 1.0f;
    494 	}
    495 };
    496 
    497 RandomGroup::RandomGroup (Context& context, const char* name, const char* descr)
    498 	: TestCaseGroup	(context, name, descr)
    499 {
    500 }
    501 
    502 RandomGroup::~RandomGroup (void)
    503 {
    504 }
    505 
    506 void RandomGroup::init (void)
    507 {
    508 	const int			numAttempts				= 100;
    509 
    510 	static const int	attribCounts[]			= { 1, 2, 5 };
    511 	static const float	attribWeights[]			= { 30, 10, 1 };
    512 	static const int	primitiveCounts[]		= { 1, 5, 64 };
    513 	static const float	primitiveCountWeights[]	= { 20, 10, 1 };
    514 	static const int	indexOffsets[]			= { 0, 7, 13 };
    515 	static const float	indexOffsetWeights[]	= { 20, 20, 1 };
    516 	static const int	firsts[]				= { 0, 7, 13 };
    517 	static const float	firstWeights[]			= { 20, 20, 1 };
    518 	static const int	offsets[]				= { 0, 1, 5, 12 };
    519 	static const float	offsetWeights[]			= { 50, 10, 10, 10 };
    520 	static const int	strides[]				= { 0, 7, 16, 17 };
    521 	static const float	strideWeights[]			= { 50, 10, 10, 10 };
    522 
    523 	static const gls::DrawTestSpec::Primitive primitives[] =
    524 	{
    525 		gls::DrawTestSpec::PRIMITIVE_POINTS,
    526 		gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
    527 		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
    528 		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
    529 		gls::DrawTestSpec::PRIMITIVE_LINES,
    530 		gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
    531 		gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
    532 	};
    533 	const UniformWeightArray<DE_LENGTH_OF_ARRAY(primitives)> primitiveWeights;
    534 
    535 	static const gls::DrawTestSpec::DrawMethod drawMethods[] =
    536 	{
    537 		gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS,
    538 		gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS,
    539 	};
    540 	const UniformWeightArray<DE_LENGTH_OF_ARRAY(drawMethods)> drawMethodWeights;
    541 
    542 	static const gls::DrawTestSpec::IndexType indexTypes[] =
    543 	{
    544 		gls::DrawTestSpec::INDEXTYPE_BYTE,
    545 		gls::DrawTestSpec::INDEXTYPE_SHORT,
    546 	};
    547 	const UniformWeightArray<DE_LENGTH_OF_ARRAY(indexTypes)> indexTypeWeights;
    548 
    549 	static const gls::DrawTestSpec::Storage storages[] =
    550 	{
    551 		gls::DrawTestSpec::STORAGE_USER,
    552 		gls::DrawTestSpec::STORAGE_BUFFER,
    553 	};
    554 	const UniformWeightArray<DE_LENGTH_OF_ARRAY(storages)> storageWeights;
    555 
    556 	static const gls::DrawTestSpec::InputType inputTypes[] =
    557 	{
    558 		gls::DrawTestSpec::INPUTTYPE_FLOAT,
    559 		gls::DrawTestSpec::INPUTTYPE_FIXED,
    560 		gls::DrawTestSpec::INPUTTYPE_BYTE,
    561 		gls::DrawTestSpec::INPUTTYPE_SHORT,
    562 		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE,
    563 		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT
    564 	};
    565 	const UniformWeightArray<DE_LENGTH_OF_ARRAY(inputTypes)> inputTypeWeights;
    566 
    567 	static const gls::DrawTestSpec::OutputType outputTypes[] =
    568 	{
    569 		gls::DrawTestSpec::OUTPUTTYPE_FLOAT,
    570 		gls::DrawTestSpec::OUTPUTTYPE_VEC2,
    571 		gls::DrawTestSpec::OUTPUTTYPE_VEC3,
    572 		gls::DrawTestSpec::OUTPUTTYPE_VEC4,
    573 	};
    574 	const UniformWeightArray<DE_LENGTH_OF_ARRAY(outputTypes)> outputTypeWeights;
    575 
    576 	static const gls::DrawTestSpec::Usage usages[] =
    577 	{
    578 		gls::DrawTestSpec::USAGE_STATIC_DRAW,
    579 		gls::DrawTestSpec::USAGE_DYNAMIC_DRAW,
    580 		gls::DrawTestSpec::USAGE_STREAM_DRAW,
    581 	};
    582 	const UniformWeightArray<DE_LENGTH_OF_ARRAY(usages)> usageWeights;
    583 
    584 	static const deUint32 blacklistedCases[]=
    585 	{
    586 		3153,	//!< extremely narrow triangle, results depend on sample positions
    587 	};
    588 
    589 	std::set<deUint32>	insertedHashes;
    590 	size_t				insertedCount = 0;
    591 
    592 	for (int ndx = 0; ndx < numAttempts; ++ndx)
    593 	{
    594 		de::Random random(0xc551393 + ndx); // random does not depend on previous cases
    595 
    596 		int					attributeCount = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(attribCounts), DE_ARRAY_END(attribCounts), attribWeights);
    597 		gls::DrawTestSpec	spec;
    598 
    599 		spec.apiType				= glu::ApiType::es(2,0);
    600 		spec.primitive				= random.chooseWeighted<gls::DrawTestSpec::Primitive>	(DE_ARRAY_BEGIN(primitives),		DE_ARRAY_END(primitives),		primitiveWeights.weights);
    601 		spec.primitiveCount			= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(primitiveCounts),	DE_ARRAY_END(primitiveCounts),	primitiveCountWeights);
    602 		spec.drawMethod				= random.chooseWeighted<gls::DrawTestSpec::DrawMethod>	(DE_ARRAY_BEGIN(drawMethods),		DE_ARRAY_END(drawMethods),		drawMethodWeights.weights);
    603 		spec.indexType				= random.chooseWeighted<gls::DrawTestSpec::IndexType>	(DE_ARRAY_BEGIN(indexTypes),		DE_ARRAY_END(indexTypes),		indexTypeWeights.weights);
    604 		spec.indexPointerOffset		= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indexOffsets),		DE_ARRAY_END(indexOffsets),		indexOffsetWeights);
    605 		spec.indexStorage			= random.chooseWeighted<gls::DrawTestSpec::Storage>		(DE_ARRAY_BEGIN(storages),			DE_ARRAY_END(storages),			storageWeights.weights);
    606 		spec.first					= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(firsts),			DE_ARRAY_END(firsts),			firstWeights);
    607 		spec.indexMin				= 0;
    608 		spec.indexMax				= 0;
    609 		spec.instanceCount			= 0;
    610 
    611 		// check spec is legal
    612 		if (!spec.valid())
    613 			continue;
    614 
    615 		for (int attrNdx = 0; attrNdx < attributeCount;)
    616 		{
    617 			bool valid;
    618 			gls::DrawTestSpec::AttributeSpec attribSpec;
    619 
    620 			attribSpec.inputType			= random.chooseWeighted<gls::DrawTestSpec::InputType>	(DE_ARRAY_BEGIN(inputTypes),		DE_ARRAY_END(inputTypes),		inputTypeWeights.weights);
    621 			attribSpec.outputType			= random.chooseWeighted<gls::DrawTestSpec::OutputType>	(DE_ARRAY_BEGIN(outputTypes),		DE_ARRAY_END(outputTypes),		outputTypeWeights.weights);
    622 			attribSpec.storage				= random.chooseWeighted<gls::DrawTestSpec::Storage>		(DE_ARRAY_BEGIN(storages),			DE_ARRAY_END(storages),			storageWeights.weights);
    623 			attribSpec.usage				= random.chooseWeighted<gls::DrawTestSpec::Usage>		(DE_ARRAY_BEGIN(usages),			DE_ARRAY_END(usages),			usageWeights.weights);
    624 			attribSpec.componentCount		= random.getInt(1, 4);
    625 			attribSpec.offset				= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(offsets), DE_ARRAY_END(offsets), offsetWeights);
    626 			attribSpec.stride				= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(strides), DE_ARRAY_END(strides), strideWeights);
    627 			attribSpec.normalize			= random.getBool();
    628 			attribSpec.instanceDivisor		= 0;
    629 			attribSpec.useDefaultAttribute	= random.getBool();
    630 
    631 			// check spec is legal
    632 			valid = attribSpec.valid(spec.apiType);
    633 
    634 			// we do not want interleaved elements. (Might result in some weird floating point values)
    635 			if (attribSpec.stride && attribSpec.componentCount * gls::DrawTestSpec::inputTypeSize(attribSpec.inputType) > attribSpec.stride)
    636 				valid = false;
    637 
    638 			// try again if not valid
    639 			if (valid)
    640 			{
    641 				spec.attribs.push_back(attribSpec);
    642 				++attrNdx;
    643 			}
    644 		}
    645 
    646 		// Do not collapse all vertex positions to a single positions
    647 		if (spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
    648 			spec.attribs[0].instanceDivisor = 0;
    649 
    650 		// Is render result meaningful?
    651 		{
    652 			// Only one vertex
    653 			if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && spec.indexMin == spec.indexMax && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
    654 				continue;
    655 			if (spec.attribs[0].useDefaultAttribute && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
    656 				continue;
    657 
    658 			// Triangle only on one axis
    659 			if (spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLES || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP)
    660 			{
    661 				if (spec.attribs[0].componentCount == 1)
    662 					continue;
    663 				if (spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_FLOAT || spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_INT || spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_UINT)
    664 					continue;
    665 				if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && (spec.indexMax - spec.indexMin) < 2)
    666 					continue;
    667 			}
    668 		}
    669 
    670 		// Add case
    671 		{
    672 			deUint32 hash = spec.hash();
    673 			for (int attrNdx = 0; attrNdx < attributeCount; ++attrNdx)
    674 				hash = (hash << 2) ^ (deUint32)spec.attribs[attrNdx].hash();
    675 
    676 			if (insertedHashes.find(hash) == insertedHashes.end() &&
    677 				!de::contains(DE_ARRAY_BEGIN(blacklistedCases), DE_ARRAY_END(blacklistedCases), hash))
    678 			{
    679 				// Only aligned cases
    680 				if (spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET &&
    681 					spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
    682 					this->addChild(new gls::DrawTest(m_testCtx, m_context.getRenderContext(), spec, de::toString(insertedCount).c_str(), spec.getDesc().c_str()));
    683 				insertedHashes.insert(hash);
    684 
    685 				++insertedCount;
    686 			}
    687 		}
    688 	}
    689 }
    690 
    691 } // anonymous
    692 
    693 DrawTests::DrawTests (Context& context)
    694 	: TestCaseGroup(context, "draw", "Drawing tests")
    695 {
    696 }
    697 
    698 DrawTests::~DrawTests (void)
    699 {
    700 }
    701 
    702 void DrawTests::init (void)
    703 {
    704 	// Basic
    705 	{
    706 		const gls::DrawTestSpec::DrawMethod basicMethods[] =
    707 		{
    708 			gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS,
    709 			gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS,
    710 		};
    711 
    712 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
    713 		{
    714 			std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
    715 			std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
    716 
    717 			this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));
    718 		}
    719 	}
    720 
    721 	// Random
    722 
    723 	this->addChild(new RandomGroup(m_context, "random", "random draw commands."));
    724 }
    725 
    726 } // Functional
    727 } // gles2
    728 } // deqp
    729