1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.0 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Vertex array and buffer tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "es2fVertexArrayTest.hpp"
25 #include "glsVertexArrayTests.hpp"
26
27 #include "glwEnums.hpp"
28
29 using namespace deqp::gls;
30
31 namespace deqp
32 {
33 namespace gles2
34 {
35 namespace Functional
36 {
37
38 template<class T>
typeToString(T t)39 static std::string typeToString (T t)
40 {
41 std::stringstream strm;
42 strm << t;
43 return strm.str();
44 }
45
46
47 class SingleVertexArrayUsageTests : public TestCaseGroup
48 {
49 public:
50 SingleVertexArrayUsageTests (Context& context);
51 virtual ~SingleVertexArrayUsageTests (void);
52
53 virtual void init (void);
54
55 private:
56 SingleVertexArrayUsageTests (const SingleVertexArrayUsageTests& other);
57 SingleVertexArrayUsageTests& operator= (const SingleVertexArrayUsageTests& other);
58 };
59
SingleVertexArrayUsageTests(Context & context)60 SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context)
61 : TestCaseGroup(context, "usages", "Single vertex atribute, usage")
62 {
63 }
64
~SingleVertexArrayUsageTests(void)65 SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void)
66 {
67 }
68
init(void)69 void SingleVertexArrayUsageTests::init (void)
70 {
71 // Test usage
72 Array::Usage usages[] = {Array::USAGE_STATIC_DRAW, Array::USAGE_STREAM_DRAW, Array::USAGE_DYNAMIC_DRAW};
73 int counts[] = {1, 256};
74 int strides[] = {0, -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
75 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE};
76
77 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
78 {
79 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
80 {
81 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
82 {
83 for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
84 {
85 const int componentCount = 2;
86 const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * componentCount : strides[strideNdx]);
87 const bool aligned = (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
88 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
89 Array::OUTPUTTYPE_VEC2,
90 Array::STORAGE_BUFFER,
91 usages[usageNdx],
92 componentCount,
93 0,
94 stride,
95 false,
96 GLValue::getMinValue(inputTypes[inputTypeNdx]),
97 GLValue::getMaxValue(inputTypes[inputTypeNdx]));
98
99 MultiVertexArrayTest::Spec spec;
100 spec.primitive = Array::PRIMITIVE_TRIANGLES;
101 spec.drawCount = counts[countNdx];
102 spec.first = 0;
103 spec.arrays.push_back(arraySpec);
104
105 std::string name = spec.getName();
106
107 if (aligned)
108 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
109 }
110 }
111 }
112 }
113 }
114
115 class SingleVertexArrayStrideTests : public TestCaseGroup
116 {
117 public:
118 SingleVertexArrayStrideTests (Context& context);
119 virtual ~SingleVertexArrayStrideTests (void);
120
121 virtual void init (void);
122
123 private:
124 SingleVertexArrayStrideTests (const SingleVertexArrayStrideTests& other);
125 SingleVertexArrayStrideTests& operator= (const SingleVertexArrayStrideTests& other);
126 };
127
SingleVertexArrayStrideTests(Context & context)128 SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context)
129 : TestCaseGroup(context, "strides", "Single stride vertex atribute")
130 {
131 }
132
~SingleVertexArrayStrideTests(void)133 SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void)
134 {
135 }
136
init(void)137 void SingleVertexArrayStrideTests::init (void)
138 {
139 // Test strides with different input types, component counts and storage, Usage(?)
140 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED};
141 Array::Storage storages[] = {Array::STORAGE_USER, Array::STORAGE_BUFFER};
142 int counts[] = {1, 256};
143 int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
144
145 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
146 {
147 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
148 {
149 for (int componentCount = 2; componentCount < 5; componentCount++)
150 {
151 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
152 {
153 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
154 {
155 const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * componentCount : strides[strideNdx]);
156 const bool bufferAligned = (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
157
158 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
159 Array::OUTPUTTYPE_VEC4,
160 storages[storageNdx],
161 Array::USAGE_DYNAMIC_DRAW,
162 componentCount,
163 0,
164 stride,
165 false,
166 GLValue::getMinValue(inputTypes[inputTypeNdx]),
167 GLValue::getMaxValue(inputTypes[inputTypeNdx]));
168
169 MultiVertexArrayTest::Spec spec;
170 spec.primitive = Array::PRIMITIVE_TRIANGLES;
171 spec.drawCount = counts[countNdx];
172 spec.first = 0;
173 spec.arrays.push_back(arraySpec);
174
175 std::string name = spec.getName();
176 if (bufferAligned)
177 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
178 }
179 }
180 }
181 }
182 }
183 }
184
185 class SingleVertexArrayFirstTests : public TestCaseGroup
186 {
187 public:
188 SingleVertexArrayFirstTests (Context& context);
189 virtual ~SingleVertexArrayFirstTests (void);
190
191 virtual void init (void);
192
193 private:
194 SingleVertexArrayFirstTests (const SingleVertexArrayFirstTests& other);
195 SingleVertexArrayFirstTests& operator= (const SingleVertexArrayFirstTests& other);
196 };
197
SingleVertexArrayFirstTests(Context & context)198 SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context)
199 : TestCaseGroup(context, "first", "Single vertex atribute different first values")
200 {
201 }
202
~SingleVertexArrayFirstTests(void)203 SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void)
204 {
205 }
206
init(void)207 void SingleVertexArrayFirstTests::init (void)
208 {
209 // Test strides with different input types, component counts and storage, Usage(?)
210 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_FIXED};
211 int counts[] = {5, 256};
212 int firsts[] = {6, 24};
213 int offsets[] = {1, 16, 17};
214 int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
215
216 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
217 {
218 for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
219 {
220 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
221 {
222 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
223 {
224 for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++)
225 {
226 const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
227 const bool aligned = ((stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0) && (offsets[offsetNdx] % Array::inputTypeSize(inputTypes[inputTypeNdx]) == 0);
228
229 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
230 Array::OUTPUTTYPE_VEC2,
231 Array::STORAGE_BUFFER,
232 Array::USAGE_DYNAMIC_DRAW,
233 2,
234 offsets[offsetNdx],
235 stride,
236 false,
237 GLValue::getMinValue(inputTypes[inputTypeNdx]),
238 GLValue::getMaxValue(inputTypes[inputTypeNdx]));
239
240 MultiVertexArrayTest::Spec spec;
241 spec.primitive = Array::PRIMITIVE_TRIANGLES;
242 spec.drawCount = counts[countNdx];
243 spec.first = firsts[firstNdx];
244 spec.arrays.push_back(arraySpec);
245
246 std::string name = Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]);
247 if (aligned)
248 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
249 }
250 }
251 }
252 }
253 }
254 }
255
256 class SingleVertexArrayOffsetTests : public TestCaseGroup
257 {
258 public:
259 SingleVertexArrayOffsetTests (Context& context);
260 virtual ~SingleVertexArrayOffsetTests (void);
261
262 virtual void init (void);
263
264 private:
265 SingleVertexArrayOffsetTests (const SingleVertexArrayOffsetTests& other);
266 SingleVertexArrayOffsetTests& operator= (const SingleVertexArrayOffsetTests& other);
267 };
268
SingleVertexArrayOffsetTests(Context & context)269 SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context)
270 : TestCaseGroup(context, "offset", "Single vertex atribute offset element")
271 {
272 }
273
~SingleVertexArrayOffsetTests(void)274 SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void)
275 {
276 }
277
init(void)278 void SingleVertexArrayOffsetTests::init (void)
279 {
280 // Test strides with different input types, component counts and storage, Usage(?)
281 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_FIXED};
282 int counts[] = {1, 256};
283 int offsets[] = {1, 4, 17, 32};
284 int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
285
286 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
287 {
288 for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
289 {
290 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
291 {
292 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
293 {
294 const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
295 const bool aligned = ((stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0) && ((offsets[offsetNdx] % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0);
296
297 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
298 Array::OUTPUTTYPE_VEC2,
299 Array::STORAGE_BUFFER,
300 Array::USAGE_DYNAMIC_DRAW,
301 2,
302 offsets[offsetNdx],
303 stride,
304 false,
305 GLValue::getMinValue(inputTypes[inputTypeNdx]),
306 GLValue::getMaxValue(inputTypes[inputTypeNdx]));
307
308 MultiVertexArrayTest::Spec spec;
309 spec.primitive = Array::PRIMITIVE_TRIANGLES;
310 spec.drawCount = counts[countNdx];
311 spec.first = 0;
312 spec.arrays.push_back(arraySpec);
313
314 std::string name = spec.getName();
315 if (aligned)
316 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
317 }
318 }
319 }
320 }
321 }
322
323 class SingleVertexArrayNormalizeTests : public TestCaseGroup
324 {
325 public:
326 SingleVertexArrayNormalizeTests (Context& context);
327 virtual ~SingleVertexArrayNormalizeTests (void);
328
329 virtual void init (void);
330
331 private:
332 SingleVertexArrayNormalizeTests (const SingleVertexArrayNormalizeTests& other);
333 SingleVertexArrayNormalizeTests& operator= (const SingleVertexArrayNormalizeTests& other);
334 };
335
SingleVertexArrayNormalizeTests(Context & context)336 SingleVertexArrayNormalizeTests::SingleVertexArrayNormalizeTests (Context& context)
337 : TestCaseGroup(context, "normalize", "Single normalize vertex atribute")
338 {
339 }
340
~SingleVertexArrayNormalizeTests(void)341 SingleVertexArrayNormalizeTests::~SingleVertexArrayNormalizeTests (void)
342 {
343 }
344
init(void)345 void SingleVertexArrayNormalizeTests::init (void)
346 {
347 // Test normalization with different input types, component counts and storage
348 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED};
349 Array::Storage storages[] = {Array::STORAGE_USER};
350 int counts[] = {1, 256};
351
352 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
353 {
354 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
355 {
356 for (int componentCount = 2; componentCount < 5; componentCount++)
357 {
358 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
359 {
360 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
361 Array::OUTPUTTYPE_VEC4,
362 storages[storageNdx],
363 Array::USAGE_DYNAMIC_DRAW,
364 componentCount,
365 0,
366 0,
367 true,
368 GLValue::getMinValue(inputTypes[inputTypeNdx]),
369 GLValue::getMaxValue(inputTypes[inputTypeNdx]));
370
371 MultiVertexArrayTest::Spec spec;
372 spec.primitive = Array::PRIMITIVE_TRIANGLES;
373 spec.drawCount = counts[countNdx];
374 spec.first = 0;
375 spec.arrays.push_back(arraySpec);
376
377 std::string name = spec.getName();
378 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
379 }
380 }
381 }
382 }
383 }
384
385 class SingleVertexArrayOutputTypeTests : public TestCaseGroup
386 {
387 public:
388 SingleVertexArrayOutputTypeTests (Context& context);
389 virtual ~SingleVertexArrayOutputTypeTests (void);
390
391 virtual void init (void);
392
393 private:
394 SingleVertexArrayOutputTypeTests (const SingleVertexArrayOutputTypeTests& other);
395 SingleVertexArrayOutputTypeTests& operator= (const SingleVertexArrayOutputTypeTests& other);
396 };
397
SingleVertexArrayOutputTypeTests(Context & context)398 SingleVertexArrayOutputTypeTests::SingleVertexArrayOutputTypeTests (Context& context)
399 : TestCaseGroup(context, "output_types", "Single output type vertex atribute")
400 {
401 }
402
~SingleVertexArrayOutputTypeTests(void)403 SingleVertexArrayOutputTypeTests::~SingleVertexArrayOutputTypeTests (void)
404 {
405 }
406
init(void)407 void SingleVertexArrayOutputTypeTests::init (void)
408 {
409 // Test output types with different input types, component counts and storage, Usage?, Precision?, float?
410 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED};
411 Array::OutputType outputTypes[] = {Array::OUTPUTTYPE_VEC2, Array::OUTPUTTYPE_VEC3, Array::OUTPUTTYPE_VEC4};
412 Array::Storage storages[] = {Array::STORAGE_USER};
413 int counts[] = {1, 256};
414
415 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
416 {
417 for (int outputTypeNdx = 0; outputTypeNdx < DE_LENGTH_OF_ARRAY(outputTypes); outputTypeNdx++)
418 {
419 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
420 {
421 for (int componentCount = 2; componentCount < 5; componentCount++)
422 {
423 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
424 {
425 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
426 outputTypes[outputTypeNdx],
427 storages[storageNdx],
428 Array::USAGE_DYNAMIC_DRAW,
429 componentCount,
430 0,
431 0,
432 false,
433 GLValue::getMinValue(inputTypes[inputTypeNdx]),
434 GLValue::getMaxValue(inputTypes[inputTypeNdx]));
435
436 MultiVertexArrayTest::Spec spec;
437 spec.primitive = Array::PRIMITIVE_TRIANGLES;
438 spec.drawCount = counts[countNdx];
439 spec.first = 0;
440 spec.arrays.push_back(arraySpec);
441
442 std::string name = spec.getName();
443 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
444 }
445 }
446 }
447 }
448 }
449 }
450
451 class SingleVertexArrayTestGroup : public TestCaseGroup
452 {
453 public:
454 SingleVertexArrayTestGroup (Context& context);
455 virtual ~SingleVertexArrayTestGroup (void);
456
457 virtual void init (void);
458
459 private:
460 SingleVertexArrayTestGroup (const SingleVertexArrayTestGroup& other);
461 SingleVertexArrayTestGroup& operator= (const SingleVertexArrayTestGroup& other);
462 };
463
SingleVertexArrayTestGroup(Context & context)464 SingleVertexArrayTestGroup::SingleVertexArrayTestGroup (Context& context)
465 : TestCaseGroup(context, "single_attribute", "Single vertex atribute")
466 {
467 }
468
~SingleVertexArrayTestGroup(void)469 SingleVertexArrayTestGroup::~SingleVertexArrayTestGroup (void)
470 {
471 }
472
init(void)473 void SingleVertexArrayTestGroup::init (void)
474 {
475 addChild(new SingleVertexArrayStrideTests(m_context));
476 addChild(new SingleVertexArrayNormalizeTests(m_context));
477 addChild(new SingleVertexArrayOutputTypeTests(m_context));
478 addChild(new SingleVertexArrayUsageTests(m_context));
479 addChild(new SingleVertexArrayOffsetTests(m_context));
480 addChild(new SingleVertexArrayFirstTests(m_context));
481 }
482
483 class MultiVertexArrayCountTests : public TestCaseGroup
484 {
485 public:
486 MultiVertexArrayCountTests (Context& context);
487 virtual ~MultiVertexArrayCountTests (void);
488
489 virtual void init (void);
490
491 private:
492 MultiVertexArrayCountTests (const MultiVertexArrayCountTests& other);
493 MultiVertexArrayCountTests& operator= (const MultiVertexArrayCountTests& other);
494
495 std::string getTestName (const MultiVertexArrayTest::Spec& spec);
496 };
497
MultiVertexArrayCountTests(Context & context)498 MultiVertexArrayCountTests::MultiVertexArrayCountTests (Context& context)
499 : TestCaseGroup(context, "attribute_count", "Attribute counts")
500 {
501 }
502
~MultiVertexArrayCountTests(void)503 MultiVertexArrayCountTests::~MultiVertexArrayCountTests (void)
504 {
505 }
506
getTestName(const MultiVertexArrayTest::Spec & spec)507 std::string MultiVertexArrayCountTests::getTestName (const MultiVertexArrayTest::Spec& spec)
508 {
509 std::stringstream name;
510 name
511 << spec.arrays.size();
512
513 return name.str();
514 }
515
init(void)516 void MultiVertexArrayCountTests::init (void)
517 {
518 // Test attribute counts
519 int arrayCounts[] = {2, 3, 4, 5, 6, 7, 8};
520
521 for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
522 {
523 MultiVertexArrayTest::Spec spec;
524
525 spec.primitive = Array::PRIMITIVE_TRIANGLES;
526 spec.drawCount = 256;
527 spec.first = 0;
528
529 for (int arrayNdx = 0; arrayNdx < arrayCounts[arrayCountNdx]; arrayNdx++)
530 {
531 MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
532 Array::OUTPUTTYPE_VEC2,
533 Array::STORAGE_USER,
534 Array::USAGE_DYNAMIC_DRAW,
535 2,
536 0,
537 0,
538 false,
539 GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
540 GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
541
542 spec.arrays.push_back(arraySpec);
543 }
544
545 std::string name = getTestName(spec);
546 std::string desc = getTestName(spec);
547
548 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
549 }
550 }
551
552 class MultiVertexArrayStorageTests : public TestCaseGroup
553 {
554 public:
555 MultiVertexArrayStorageTests (Context& context);
556 virtual ~MultiVertexArrayStorageTests (void);
557
558 virtual void init (void);
559
560 private:
561 MultiVertexArrayStorageTests (const MultiVertexArrayStorageTests& other);
562 MultiVertexArrayStorageTests& operator= (const MultiVertexArrayStorageTests& other);
563
564 void addStorageCases (MultiVertexArrayTest::Spec spec, int depth);
565 std::string getTestName (const MultiVertexArrayTest::Spec& spec);
566 };
567
MultiVertexArrayStorageTests(Context & context)568 MultiVertexArrayStorageTests::MultiVertexArrayStorageTests (Context& context)
569 : TestCaseGroup(context, "storage", "Attribute storages")
570 {
571 }
572
~MultiVertexArrayStorageTests(void)573 MultiVertexArrayStorageTests::~MultiVertexArrayStorageTests (void)
574 {
575 }
576
getTestName(const MultiVertexArrayTest::Spec & spec)577 std::string MultiVertexArrayStorageTests::getTestName (const MultiVertexArrayTest::Spec& spec)
578 {
579 std::stringstream name;
580 name
581 << spec.arrays.size();
582
583 for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
584 {
585 name
586 << "_"
587 << Array::storageToString(spec.arrays[arrayNdx].storage);
588 }
589
590 return name.str();
591 }
592
addStorageCases(MultiVertexArrayTest::Spec spec,int depth)593 void MultiVertexArrayStorageTests::addStorageCases (MultiVertexArrayTest::Spec spec, int depth)
594 {
595 if (depth == 0)
596 {
597 // Skip trivial case, used elsewhere
598 bool ok = false;
599 for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
600 {
601 if (spec.arrays[arrayNdx].storage != Array::STORAGE_USER)
602 {
603 ok = true;
604 break;
605 }
606 }
607
608 if (!ok)
609 return;
610
611 std::string name = getTestName(spec);
612 std::string desc = getTestName(spec);
613
614 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
615 return;
616 }
617
618 Array::Storage storages[] = {Array::STORAGE_USER, Array::STORAGE_BUFFER};
619 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
620 {
621 MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
622 Array::OUTPUTTYPE_VEC2,
623 storages[storageNdx],
624 Array::USAGE_DYNAMIC_DRAW,
625 2,
626 0,
627 0,
628 false,
629 GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
630 GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
631
632 MultiVertexArrayTest::Spec _spec = spec;
633 _spec.arrays.push_back(arraySpec);
634 addStorageCases(_spec, depth-1);
635 }
636 }
637
638
init(void)639 void MultiVertexArrayStorageTests::init (void)
640 {
641 // Test different storages
642 int arrayCounts[] = {3};
643
644 MultiVertexArrayTest::Spec spec;
645
646 spec.primitive = Array::PRIMITIVE_TRIANGLES;
647 spec.drawCount = 256;
648 spec.first = 0;
649
650 for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
651 addStorageCases(spec, arrayCounts[arrayCountNdx]);
652 }
653
654 class MultiVertexArrayStrideTests : public TestCaseGroup
655 {
656 public:
657 MultiVertexArrayStrideTests (Context& context);
658 virtual ~MultiVertexArrayStrideTests (void);
659
660 virtual void init (void);
661
662 private:
663 MultiVertexArrayStrideTests (const MultiVertexArrayStrideTests& other);
664 MultiVertexArrayStrideTests& operator= (const MultiVertexArrayStrideTests& other);
665
666 void addStrideCases (MultiVertexArrayTest::Spec spec, int depth);
667 std::string getTestName (const MultiVertexArrayTest::Spec& spec);
668 };
669
MultiVertexArrayStrideTests(Context & context)670 MultiVertexArrayStrideTests::MultiVertexArrayStrideTests (Context& context)
671 : TestCaseGroup(context, "stride", "Strides")
672 {
673 }
674
~MultiVertexArrayStrideTests(void)675 MultiVertexArrayStrideTests::~MultiVertexArrayStrideTests (void)
676 {
677 }
678
getTestName(const MultiVertexArrayTest::Spec & spec)679 std::string MultiVertexArrayStrideTests::getTestName (const MultiVertexArrayTest::Spec& spec)
680 {
681 std::stringstream name;
682
683 name
684 << spec.arrays.size();
685
686 for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
687 {
688 name
689 << "_"
690 << Array::inputTypeToString(spec.arrays[arrayNdx].inputType)
691 << spec.arrays[arrayNdx].componentCount << "_"
692 << spec.arrays[arrayNdx].stride;
693 }
694
695 return name.str();
696 }
697
init(void)698 void MultiVertexArrayStrideTests::init (void)
699 {
700 // Test different strides, with multiple arrays, input types??
701 int arrayCounts[] = {3};
702
703 MultiVertexArrayTest::Spec spec;
704
705 spec.primitive = Array::PRIMITIVE_TRIANGLES;
706 spec.drawCount = 256;
707 spec.first = 0;
708
709 for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
710 addStrideCases(spec, arrayCounts[arrayCountNdx]);
711 }
712
addStrideCases(MultiVertexArrayTest::Spec spec,int depth)713 void MultiVertexArrayStrideTests::addStrideCases (MultiVertexArrayTest::Spec spec, int depth)
714 {
715 if (depth == 0)
716 {
717 std::string name = getTestName(spec);
718 std::string desc = getTestName(spec);
719 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
720 return;
721 }
722
723 int strides[] = {0, -1, 17, 32};
724
725 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
726 {
727 const int componentCount = 2;
728 MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
729 Array::OUTPUTTYPE_VEC2,
730 Array::STORAGE_USER,
731 Array::USAGE_DYNAMIC_DRAW,
732 componentCount,
733 0,
734 (strides[strideNdx] >= 0 ? strides[strideNdx] : componentCount * Array::inputTypeSize(Array::INPUTTYPE_FLOAT)),
735 false,
736 GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
737 GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
738
739 MultiVertexArrayTest::Spec _spec = spec;
740 _spec.arrays.push_back(arraySpec);
741 addStrideCases(_spec, depth-1);
742 }
743 }
744
745 class MultiVertexArrayOutputTests : public TestCaseGroup
746 {
747 public:
748 MultiVertexArrayOutputTests (Context& context);
749 virtual ~MultiVertexArrayOutputTests (void);
750
751 virtual void init (void);
752
753 private:
754 MultiVertexArrayOutputTests (const MultiVertexArrayOutputTests& other);
755 MultiVertexArrayOutputTests& operator= (const MultiVertexArrayOutputTests& other);
756
757 void addInputTypeCases (MultiVertexArrayTest::Spec spec, int depth);
758 std::string getTestName (const MultiVertexArrayTest::Spec& spec);
759 };
760
MultiVertexArrayOutputTests(Context & context)761 MultiVertexArrayOutputTests::MultiVertexArrayOutputTests (Context& context)
762 : TestCaseGroup(context, "input_types", "input types")
763 {
764 }
765
~MultiVertexArrayOutputTests(void)766 MultiVertexArrayOutputTests::~MultiVertexArrayOutputTests (void)
767 {
768 }
769
getTestName(const MultiVertexArrayTest::Spec & spec)770 std::string MultiVertexArrayOutputTests::getTestName (const MultiVertexArrayTest::Spec& spec)
771 {
772 std::stringstream name;
773
774 name
775 << spec.arrays.size();
776
777 for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
778 {
779 name
780 << "_"
781 << Array::inputTypeToString(spec.arrays[arrayNdx].inputType)
782 << spec.arrays[arrayNdx].componentCount << "_"
783 << Array::outputTypeToString(spec.arrays[arrayNdx].outputType);
784 }
785
786 return name.str();
787 }
788
init(void)789 void MultiVertexArrayOutputTests::init (void)
790 {
791 // Test different input types, with multiple arrays
792 int arrayCounts[] = {3};
793
794 MultiVertexArrayTest::Spec spec;
795
796 spec.primitive = Array::PRIMITIVE_TRIANGLES;
797 spec.drawCount = 256;
798 spec.first = 0;
799
800 for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
801 addInputTypeCases(spec, arrayCounts[arrayCountNdx]);
802 }
803
addInputTypeCases(MultiVertexArrayTest::Spec spec,int depth)804 void MultiVertexArrayOutputTests::addInputTypeCases (MultiVertexArrayTest::Spec spec, int depth)
805 {
806 if (depth == 0)
807 {
808 std::string name = getTestName(spec);
809 std::string desc = getTestName(spec);
810 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
811 return;
812 }
813
814 Array::InputType inputTypes[] = {Array::INPUTTYPE_FIXED, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT};
815 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
816 {
817 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
818 Array::OUTPUTTYPE_VEC2,
819 Array::STORAGE_USER,
820 Array::USAGE_DYNAMIC_DRAW,
821 2,
822 0,
823 0,
824 false,
825 GLValue::getMinValue(inputTypes[inputTypeNdx]),
826 GLValue::getMaxValue(inputTypes[inputTypeNdx]));
827
828 MultiVertexArrayTest::Spec _spec = spec;
829 _spec.arrays.push_back(arraySpec);
830 addInputTypeCases(_spec, depth-1);
831 }
832 }
833
834 class MultiVertexArrayTestGroup : public TestCaseGroup
835 {
836 public:
837 MultiVertexArrayTestGroup (Context& context);
838 virtual ~MultiVertexArrayTestGroup (void);
839
840 virtual void init (void);
841
842 private:
843 MultiVertexArrayTestGroup (const MultiVertexArrayTestGroup& other);
844 MultiVertexArrayTestGroup& operator= (const MultiVertexArrayTestGroup& other);
845 };
846
MultiVertexArrayTestGroup(Context & context)847 MultiVertexArrayTestGroup::MultiVertexArrayTestGroup (Context& context)
848 : TestCaseGroup(context, "multiple_attributes", "Multiple vertex atributes")
849 {
850 }
851
~MultiVertexArrayTestGroup(void)852 MultiVertexArrayTestGroup::~MultiVertexArrayTestGroup (void)
853 {
854 }
855
init(void)856 void MultiVertexArrayTestGroup::init (void)
857 {
858 addChild(new MultiVertexArrayCountTests(m_context));
859 addChild(new MultiVertexArrayStorageTests(m_context));
860 addChild(new MultiVertexArrayStrideTests(m_context));
861 addChild(new MultiVertexArrayOutputTests(m_context));
862 }
863
VertexArrayTestGroup(Context & context)864 VertexArrayTestGroup::VertexArrayTestGroup (Context& context)
865 : TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests")
866 {
867 }
868
~VertexArrayTestGroup(void)869 VertexArrayTestGroup::~VertexArrayTestGroup (void)
870 {
871 }
872
init(void)873 void VertexArrayTestGroup::init (void)
874 {
875 addChild(new SingleVertexArrayTestGroup(m_context));
876 addChild(new MultiVertexArrayTestGroup(m_context));
877 }
878
879 } // Functional
880 } // gles2
881 } // deqp
882
883