1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Drawing tests.
22 *//*--------------------------------------------------------------------*/
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"
32 #include "glwEnums.hpp"
45 enum TestIterationType
47 TYPE_DRAW_COUNT, // !< test with 1, 5, and 25 primitives
52 static void addTestIterations (gls::DrawTest* test, const gls::DrawTestSpec& baseSpec, TestIterationType type)
54 gls::DrawTestSpec spec(baseSpec);
56 if (type == TYPE_DRAW_COUNT)
58 spec.primitiveCount = 1;
59 test->addIteration(spec, "draw count = 1");
61 spec.primitiveCount = 5;
62 test->addIteration(spec, "draw count = 5");
64 spec.primitiveCount = 25;
65 test->addIteration(spec, "draw count = 25");
71 static void genBasicSpec (gls::DrawTestSpec& spec, gls::DrawTestSpec::DrawMethod method)
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;
83 spec.instanceCount = 1;
85 spec.attribs.resize(2);
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;
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;
111 class AttributeGroup : public TestCaseGroup
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);
120 gls::DrawTestSpec::DrawMethod m_method;
121 gls::DrawTestSpec::Primitive m_primitive;
122 gls::DrawTestSpec::IndexType m_indexType;
123 gls::DrawTestSpec::Storage m_indexStorage;
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)
135 AttributeGroup::~AttributeGroup (void)
139 void AttributeGroup::init (void)
143 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
144 gls::DrawTestSpec spec;
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;
156 spec.instanceCount = 1;
158 spec.attribs.resize(1);
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;
171 addTestIterations(test, spec, TYPE_DRAW_COUNT);
173 this->addChild(test);
176 // Multiple attribute
178 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays");
179 gls::DrawTestSpec spec;
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;
191 spec.instanceCount = 1;
193 spec.attribs.resize(2);
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;
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;
217 addTestIterations(test, spec, TYPE_DRAW_COUNT);
219 this->addChild(test);
222 // Multiple attribute, second one default.
224 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*.");
225 gls::DrawTestSpec spec;
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;
237 spec.instanceCount = 1;
239 spec.attribs.resize(2);
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;
254 gls::DrawTestSpec::InputType input;
255 gls::DrawTestSpec::OutputType output;
259 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC2, 4 },
260 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC4, 2 },
263 for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
265 const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);
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;
278 test->addIteration(spec, desc.c_str());
281 this->addChild(test);
285 class IndexGroup : public TestCaseGroup
288 IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
294 gls::DrawTestSpec::DrawMethod m_method;
297 IndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
298 : TestCaseGroup (context, name, descr)
299 , m_method (drawMethod)
303 IndexGroup::~IndexGroup (void)
307 void IndexGroup::init (void)
311 gls::DrawTestSpec::Storage storage;
312 gls::DrawTestSpec::IndexType type;
317 const IndexTest tests[] =
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 } },
322 { gls::DrawTestSpec::STORAGE_USER, gls::DrawTestSpec::INDEXTYPE_SHORT, false, { 1, 3, -1 } },
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 } },
328 gls::DrawTestSpec spec;
330 tcu::TestCaseGroup* userPtrGroup = new tcu::TestCaseGroup(m_testCtx, "user_ptr", "user pointer");
331 tcu::TestCaseGroup* unalignedUserPtrGroup = new tcu::TestCaseGroup(m_testCtx, "unaligned_user_ptr", "unaligned user pointer");
332 tcu::TestCaseGroup* bufferGroup = new tcu::TestCaseGroup(m_testCtx, "buffer", "buffer");
334 genBasicSpec(spec, m_method);
336 this->addChild(userPtrGroup);
337 this->addChild(unalignedUserPtrGroup);
338 this->addChild(bufferGroup);
340 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
342 const IndexTest& indexTest = tests[testNdx];
343 tcu::TestCaseGroup* group = (indexTest.storage == gls::DrawTestSpec::STORAGE_USER)
344 ? ((indexTest.aligned) ? (userPtrGroup) : (unalignedUserPtrGroup))
345 : ((indexTest.aligned) ? (bufferGroup) : (DE_NULL));
347 const std::string name = std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
348 const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type) + " in " + gls::DrawTestSpec::storageToString(indexTest.storage);
349 de::MovePtr<gls::DrawTest> test (new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str()));
351 spec.indexType = indexTest.type;
352 spec.indexStorage = indexTest.storage;
354 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
356 const std::string iterationDesc = std::string("offset ") + de::toString(indexTest.offsets[iterationNdx]);
357 spec.indexPointerOffset = indexTest.offsets[iterationNdx];
358 test->addIteration(spec, iterationDesc.c_str());
361 DE_ASSERT(spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET);
362 DE_ASSERT(spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE);
363 group->addChild(test.release());
368 class FirstGroup : public TestCaseGroup
371 FirstGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
377 gls::DrawTestSpec::DrawMethod m_method;
380 FirstGroup::FirstGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
381 : TestCaseGroup (context, name, descr)
382 , m_method (drawMethod)
386 FirstGroup::~FirstGroup (void)
390 void FirstGroup::init (void)
397 gls::DrawTestSpec spec;
398 genBasicSpec(spec, m_method);
400 for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); ++firstNdx)
402 const std::string name = std::string("first_") + de::toString(firsts[firstNdx]);
403 const std::string desc = std::string("first ") + de::toString(firsts[firstNdx]);
404 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
406 spec.first = firsts[firstNdx];
408 addTestIterations(test, spec, TYPE_DRAW_COUNT);
410 this->addChild(test);
414 class MethodGroup : public TestCaseGroup
417 MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
423 gls::DrawTestSpec::DrawMethod m_method;
426 MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
427 : TestCaseGroup (context, name, descr)
428 , m_method (drawMethod)
432 MethodGroup::~MethodGroup (void)
436 void MethodGroup::init (void)
438 const bool indexed = (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED);
439 const bool hasFirst = (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED);
441 const gls::DrawTestSpec::Primitive primitive[] =
443 gls::DrawTestSpec::PRIMITIVE_POINTS,
444 gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
445 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
446 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
447 gls::DrawTestSpec::PRIMITIVE_LINES,
448 gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
449 gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
455 this->addChild(new FirstGroup(m_context, "first", "First tests", m_method));
461 if (m_method != gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED)
462 this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
465 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
467 const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
468 const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
470 this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
474 class RandomGroup : public TestCaseGroup
477 RandomGroup (Context& context, const char* name, const char* descr);
484 struct UniformWeightArray
488 UniformWeightArray (void)
490 for (int i=0; i<SIZE; ++i)
495 RandomGroup::RandomGroup (Context& context, const char* name, const char* descr)
496 : TestCaseGroup (context, name, descr)
500 RandomGroup::~RandomGroup (void)
504 void RandomGroup::init (void)
506 const int numAttempts = 100;
508 static const int attribCounts[] = { 1, 2, 5 };
509 static const float attribWeights[] = { 30, 10, 1 };
510 static const int primitiveCounts[] = { 1, 5, 64 };
511 static const float primitiveCountWeights[] = { 20, 10, 1 };
512 static const int indexOffsets[] = { 0, 7, 13 };
513 static const float indexOffsetWeights[] = { 20, 20, 1 };
514 static const int firsts[] = { 0, 7, 13 };
515 static const float firstWeights[] = { 20, 20, 1 };
516 static const int offsets[] = { 0, 1, 5, 12 };
517 static const float offsetWeights[] = { 50, 10, 10, 10 };
518 static const int strides[] = { 0, 7, 16, 17 };
519 static const float strideWeights[] = { 50, 10, 10, 10 };
521 static const gls::DrawTestSpec::Primitive primitives[] =
523 gls::DrawTestSpec::PRIMITIVE_POINTS,
524 gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
525 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
526 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
527 gls::DrawTestSpec::PRIMITIVE_LINES,
528 gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
529 gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
531 const UniformWeightArray<DE_LENGTH_OF_ARRAY(primitives)> primitiveWeights;
533 static const gls::DrawTestSpec::DrawMethod drawMethods[] =
535 gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS,
536 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS,
538 const UniformWeightArray<DE_LENGTH_OF_ARRAY(drawMethods)> drawMethodWeights;
540 static const gls::DrawTestSpec::IndexType indexTypes[] =
542 gls::DrawTestSpec::INDEXTYPE_BYTE,
543 gls::DrawTestSpec::INDEXTYPE_SHORT,
545 const UniformWeightArray<DE_LENGTH_OF_ARRAY(indexTypes)> indexTypeWeights;
547 static const gls::DrawTestSpec::Storage storages[] =
549 gls::DrawTestSpec::STORAGE_USER,
550 gls::DrawTestSpec::STORAGE_BUFFER,
552 const UniformWeightArray<DE_LENGTH_OF_ARRAY(storages)> storageWeights;
554 static const gls::DrawTestSpec::InputType inputTypes[] =
556 gls::DrawTestSpec::INPUTTYPE_FLOAT,
557 gls::DrawTestSpec::INPUTTYPE_FIXED,
558 gls::DrawTestSpec::INPUTTYPE_BYTE,
559 gls::DrawTestSpec::INPUTTYPE_SHORT,
560 gls::DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE,
561 gls::DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT
563 const UniformWeightArray<DE_LENGTH_OF_ARRAY(inputTypes)> inputTypeWeights;
565 static const gls::DrawTestSpec::OutputType outputTypes[] =
567 gls::DrawTestSpec::OUTPUTTYPE_FLOAT,
568 gls::DrawTestSpec::OUTPUTTYPE_VEC2,
569 gls::DrawTestSpec::OUTPUTTYPE_VEC3,
570 gls::DrawTestSpec::OUTPUTTYPE_VEC4,
572 const UniformWeightArray<DE_LENGTH_OF_ARRAY(outputTypes)> outputTypeWeights;
574 static const gls::DrawTestSpec::Usage usages[] =
576 gls::DrawTestSpec::USAGE_STATIC_DRAW,
577 gls::DrawTestSpec::USAGE_DYNAMIC_DRAW,
578 gls::DrawTestSpec::USAGE_STREAM_DRAW,
580 const UniformWeightArray<DE_LENGTH_OF_ARRAY(usages)> usageWeights;
582 static const deUint32 blacklistedCases[]=
584 3153, //!< extremely narrow triangle, results depend on sample positions
587 std::set<deUint32> insertedHashes;
588 size_t insertedCount = 0;
590 for (int ndx = 0; ndx < numAttempts; ++ndx)
592 de::Random random(0xc551393 + ndx); // random does not depend on previous cases
594 int attributeCount = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(attribCounts), DE_ARRAY_END(attribCounts), attribWeights);
595 gls::DrawTestSpec spec;
597 spec.apiType = glu::ApiType::es(2,0);
598 spec.primitive = random.chooseWeighted<gls::DrawTestSpec::Primitive> (DE_ARRAY_BEGIN(primitives), DE_ARRAY_END(primitives), primitiveWeights.weights);
599 spec.primitiveCount = random.chooseWeighted<int, const int*, const float*> (DE_ARRAY_BEGIN(primitiveCounts), DE_ARRAY_END(primitiveCounts), primitiveCountWeights);
600 spec.drawMethod = random.chooseWeighted<gls::DrawTestSpec::DrawMethod> (DE_ARRAY_BEGIN(drawMethods), DE_ARRAY_END(drawMethods), drawMethodWeights.weights);
601 spec.indexType = random.chooseWeighted<gls::DrawTestSpec::IndexType> (DE_ARRAY_BEGIN(indexTypes), DE_ARRAY_END(indexTypes), indexTypeWeights.weights);
602 spec.indexPointerOffset = random.chooseWeighted<int, const int*, const float*> (DE_ARRAY_BEGIN(indexOffsets), DE_ARRAY_END(indexOffsets), indexOffsetWeights);
603 spec.indexStorage = random.chooseWeighted<gls::DrawTestSpec::Storage> (DE_ARRAY_BEGIN(storages), DE_ARRAY_END(storages), storageWeights.weights);
604 spec.first = random.chooseWeighted<int, const int*, const float*> (DE_ARRAY_BEGIN(firsts), DE_ARRAY_END(firsts), firstWeights);
607 spec.instanceCount = 0;
609 // check spec is legal
613 for (int attrNdx = 0; attrNdx < attributeCount;)
616 gls::DrawTestSpec::AttributeSpec attribSpec;
618 attribSpec.inputType = random.chooseWeighted<gls::DrawTestSpec::InputType> (DE_ARRAY_BEGIN(inputTypes), DE_ARRAY_END(inputTypes), inputTypeWeights.weights);
619 attribSpec.outputType = random.chooseWeighted<gls::DrawTestSpec::OutputType> (DE_ARRAY_BEGIN(outputTypes), DE_ARRAY_END(outputTypes), outputTypeWeights.weights);
620 attribSpec.storage = random.chooseWeighted<gls::DrawTestSpec::Storage> (DE_ARRAY_BEGIN(storages), DE_ARRAY_END(storages), storageWeights.weights);
621 attribSpec.usage = random.chooseWeighted<gls::DrawTestSpec::Usage> (DE_ARRAY_BEGIN(usages), DE_ARRAY_END(usages), usageWeights.weights);
622 attribSpec.componentCount = random.getInt(1, 4);
623 attribSpec.offset = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(offsets), DE_ARRAY_END(offsets), offsetWeights);
624 attribSpec.stride = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(strides), DE_ARRAY_END(strides), strideWeights);
625 attribSpec.normalize = random.getBool();
626 attribSpec.instanceDivisor = 0;
627 attribSpec.useDefaultAttribute = random.getBool();
629 // check spec is legal
630 valid = attribSpec.valid(spec.apiType);
632 // we do not want interleaved elements. (Might result in some weird floating point values)
633 if (attribSpec.stride && attribSpec.componentCount * gls::DrawTestSpec::inputTypeSize(attribSpec.inputType) > attribSpec.stride)
636 // try again if not valid
639 spec.attribs.push_back(attribSpec);
644 // Do not collapse all vertex positions to a single positions
645 if (spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
646 spec.attribs[0].instanceDivisor = 0;
648 // Is render result meaningful?
651 if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && spec.indexMin == spec.indexMax && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
653 if (spec.attribs[0].useDefaultAttribute && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
656 // Triangle only on one axis
657 if (spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLES || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP)
659 if (spec.attribs[0].componentCount == 1)
661 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)
663 if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && (spec.indexMax - spec.indexMin) < 2)
670 deUint32 hash = spec.hash();
671 for (int attrNdx = 0; attrNdx < attributeCount; ++attrNdx)
672 hash = (hash << 2) ^ (deUint32)spec.attribs[attrNdx].hash();
674 if (insertedHashes.find(hash) == insertedHashes.end() &&
675 !de::contains(DE_ARRAY_BEGIN(blacklistedCases), DE_ARRAY_END(blacklistedCases), hash))
677 // Only aligned cases
678 if (spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET &&
679 spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
680 this->addChild(new gls::DrawTest(m_testCtx, m_context.getRenderContext(), spec, de::toString(insertedCount).c_str(), spec.getDesc().c_str()));
681 insertedHashes.insert(hash);
691 DrawTests::DrawTests (Context& context)
692 : TestCaseGroup(context, "draw", "Drawing tests")
696 DrawTests::~DrawTests (void)
700 void DrawTests::init (void)
704 const gls::DrawTestSpec::DrawMethod basicMethods[] =
706 gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS,
707 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS,
710 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
712 std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
713 std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
715 this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));
721 this->addChild(new RandomGroup(m_context, "random", "random draw commands."));