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