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
addTestIterations(gls::DrawTest * test,const gls::DrawTestSpec & baseSpec,TestIterationType type)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
genBasicSpec(gls::DrawTestSpec & spec,gls::DrawTestSpec::DrawMethod method)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
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)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
~AttributeGroup(void)135 AttributeGroup::~AttributeGroup (void)
136 {
137 }
138
init(void)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
IndexGroup(Context & context,const char * name,const char * descr,gls::DrawTestSpec::DrawMethod drawMethod)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
~IndexGroup(void)303 IndexGroup::~IndexGroup (void)
304 {
305 }
306
init(void)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
328 gls::DrawTestSpec spec;
329
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");
333
334 genBasicSpec(spec, m_method);
335
336 this->addChild(userPtrGroup);
337 this->addChild(unalignedUserPtrGroup);
338 this->addChild(bufferGroup);
339
340 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
341 {
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));
346
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()));
350
351 spec.indexType = indexTest.type;
352 spec.indexStorage = indexTest.storage;
353
354 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
355 {
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());
359 }
360
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());
364 }
365 }
366
367
368 class FirstGroup : public TestCaseGroup
369 {
370 public:
371 FirstGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
372 ~FirstGroup (void);
373
374 void init (void);
375
376 private:
377 gls::DrawTestSpec::DrawMethod m_method;
378 };
379
FirstGroup(Context & context,const char * name,const char * descr,gls::DrawTestSpec::DrawMethod drawMethod)380 FirstGroup::FirstGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
381 : TestCaseGroup (context, name, descr)
382 , m_method (drawMethod)
383 {
384 }
385
~FirstGroup(void)386 FirstGroup::~FirstGroup (void)
387 {
388 }
389
init(void)390 void FirstGroup::init (void)
391 {
392 const int firsts[] =
393 {
394 0, 1, 17
395 };
396
397 gls::DrawTestSpec spec;
398 genBasicSpec(spec, m_method);
399
400 for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); ++firstNdx)
401 {
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());
405
406 spec.first = firsts[firstNdx];
407
408 addTestIterations(test, spec, TYPE_DRAW_COUNT);
409
410 this->addChild(test);
411 }
412 }
413
414 class MethodGroup : public TestCaseGroup
415 {
416 public:
417 MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
418 ~MethodGroup (void);
419
420 void init (void);
421
422 private:
423 gls::DrawTestSpec::DrawMethod m_method;
424 };
425
MethodGroup(Context & context,const char * name,const char * descr,gls::DrawTestSpec::DrawMethod drawMethod)426 MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
427 : TestCaseGroup (context, name, descr)
428 , m_method (drawMethod)
429 {
430 }
431
~MethodGroup(void)432 MethodGroup::~MethodGroup (void)
433 {
434 }
435
init(void)436 void MethodGroup::init (void)
437 {
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);
440
441 const gls::DrawTestSpec::Primitive primitive[] =
442 {
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
450 };
451
452 if (hasFirst)
453 {
454 // First-tests
455 this->addChild(new FirstGroup(m_context, "first", "First tests", m_method));
456 }
457
458 if (indexed)
459 {
460 // Index-tests
461 if (m_method != gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED)
462 this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
463 }
464
465 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
466 {
467 const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
468 const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
469
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));
471 }
472 }
473
474 class RandomGroup : public TestCaseGroup
475 {
476 public:
477 RandomGroup (Context& context, const char* name, const char* descr);
478 ~RandomGroup (void);
479
480 void init (void);
481 };
482
483 template <int SIZE>
484 struct UniformWeightArray
485 {
486 float weights[SIZE];
487
UniformWeightArraydeqp::gles2::Functional::__anon7e97bc810111::UniformWeightArray488 UniformWeightArray (void)
489 {
490 for (int i=0; i<SIZE; ++i)
491 weights[i] = 1.0f;
492 }
493 };
494
RandomGroup(Context & context,const char * name,const char * descr)495 RandomGroup::RandomGroup (Context& context, const char* name, const char* descr)
496 : TestCaseGroup (context, name, descr)
497 {
498 }
499
~RandomGroup(void)500 RandomGroup::~RandomGroup (void)
501 {
502 }
503
init(void)504 void RandomGroup::init (void)
505 {
506 const int numAttempts = 100;
507
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 };
520
521 static const gls::DrawTestSpec::Primitive primitives[] =
522 {
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
530 };
531 const UniformWeightArray<DE_LENGTH_OF_ARRAY(primitives)> primitiveWeights;
532
533 static const gls::DrawTestSpec::DrawMethod drawMethods[] =
534 {
535 gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS,
536 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS,
537 };
538 const UniformWeightArray<DE_LENGTH_OF_ARRAY(drawMethods)> drawMethodWeights;
539
540 static const gls::DrawTestSpec::IndexType indexTypes[] =
541 {
542 gls::DrawTestSpec::INDEXTYPE_BYTE,
543 gls::DrawTestSpec::INDEXTYPE_SHORT,
544 };
545 const UniformWeightArray<DE_LENGTH_OF_ARRAY(indexTypes)> indexTypeWeights;
546
547 static const gls::DrawTestSpec::Storage storages[] =
548 {
549 gls::DrawTestSpec::STORAGE_USER,
550 gls::DrawTestSpec::STORAGE_BUFFER,
551 };
552 const UniformWeightArray<DE_LENGTH_OF_ARRAY(storages)> storageWeights;
553
554 static const gls::DrawTestSpec::InputType inputTypes[] =
555 {
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
562 };
563 const UniformWeightArray<DE_LENGTH_OF_ARRAY(inputTypes)> inputTypeWeights;
564
565 static const gls::DrawTestSpec::OutputType outputTypes[] =
566 {
567 gls::DrawTestSpec::OUTPUTTYPE_FLOAT,
568 gls::DrawTestSpec::OUTPUTTYPE_VEC2,
569 gls::DrawTestSpec::OUTPUTTYPE_VEC3,
570 gls::DrawTestSpec::OUTPUTTYPE_VEC4,
571 };
572 const UniformWeightArray<DE_LENGTH_OF_ARRAY(outputTypes)> outputTypeWeights;
573
574 static const gls::DrawTestSpec::Usage usages[] =
575 {
576 gls::DrawTestSpec::USAGE_STATIC_DRAW,
577 gls::DrawTestSpec::USAGE_DYNAMIC_DRAW,
578 gls::DrawTestSpec::USAGE_STREAM_DRAW,
579 };
580 const UniformWeightArray<DE_LENGTH_OF_ARRAY(usages)> usageWeights;
581
582 static const deUint32 blacklistedCases[]=
583 {
584 3153, //!< extremely narrow triangle, results depend on sample positions
585 };
586
587 std::set<deUint32> insertedHashes;
588 size_t insertedCount = 0;
589
590 for (int ndx = 0; ndx < numAttempts; ++ndx)
591 {
592 de::Random random(0xc551393 + ndx); // random does not depend on previous cases
593
594 int attributeCount = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(attribCounts), DE_ARRAY_END(attribCounts), attribWeights);
595 gls::DrawTestSpec spec;
596
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);
605 spec.indexMin = 0;
606 spec.indexMax = 0;
607 spec.instanceCount = 0;
608
609 // check spec is legal
610 if (!spec.valid())
611 continue;
612
613 for (int attrNdx = 0; attrNdx < attributeCount;)
614 {
615 bool valid;
616 gls::DrawTestSpec::AttributeSpec attribSpec;
617
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();
628
629 // check spec is legal
630 valid = attribSpec.valid(spec.apiType);
631
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)
634 valid = false;
635
636 // try again if not valid
637 if (valid)
638 {
639 spec.attribs.push_back(attribSpec);
640 ++attrNdx;
641 }
642 }
643
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;
647
648 // Is render result meaningful?
649 {
650 // Only one vertex
651 if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && spec.indexMin == spec.indexMax && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
652 continue;
653 if (spec.attribs[0].useDefaultAttribute && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
654 continue;
655
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)
658 {
659 if (spec.attribs[0].componentCount == 1)
660 continue;
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)
662 continue;
663 if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && (spec.indexMax - spec.indexMin) < 2)
664 continue;
665 }
666 }
667
668 // Add case
669 {
670 deUint32 hash = spec.hash();
671 for (int attrNdx = 0; attrNdx < attributeCount; ++attrNdx)
672 hash = (hash << 2) ^ (deUint32)spec.attribs[attrNdx].hash();
673
674 if (insertedHashes.find(hash) == insertedHashes.end() &&
675 !de::contains(DE_ARRAY_BEGIN(blacklistedCases), DE_ARRAY_END(blacklistedCases), hash))
676 {
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);
682
683 ++insertedCount;
684 }
685 }
686 }
687 }
688
689 } // anonymous
690
DrawTests(Context & context)691 DrawTests::DrawTests (Context& context)
692 : TestCaseGroup(context, "draw", "Drawing tests")
693 {
694 }
695
~DrawTests(void)696 DrawTests::~DrawTests (void)
697 {
698 }
699
init(void)700 void DrawTests::init (void)
701 {
702 // Basic
703 {
704 const gls::DrawTestSpec::DrawMethod basicMethods[] =
705 {
706 gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS,
707 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS,
708 };
709
710 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
711 {
712 std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
713 std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
714
715 this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));
716 }
717 }
718
719 // Random
720
721 this->addChild(new RandomGroup(m_context, "random", "random draw commands."));
722 }
723
724 } // Functional
725 } // gles2
726 } // deqp
727