Merge "Fix color change verification in dithering tests" into nougat-cts-dev am:...
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fVertexArrayTest.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.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 "es3fVertexArrayTest.hpp"
25 #include "glsVertexArrayTests.hpp"
26
27 #include <sstream>
28
29 using namespace deqp::gls;
30
31 namespace deqp
32 {
33 namespace gles3
34 {
35 namespace Functional
36 {
37
38 class SingleVertexArrayUsageGroup : public TestCaseGroup
39 {
40 public:
41                                                                         SingleVertexArrayUsageGroup             (Context& context, Array::Usage usage);
42         virtual                                                 ~SingleVertexArrayUsageGroup    (void);
43
44         virtual void                                    init                                                    (void);
45
46 private:
47                                                                         SingleVertexArrayUsageGroup             (const SingleVertexArrayUsageGroup& other);
48         SingleVertexArrayUsageGroup&    operator=                                               (const SingleVertexArrayUsageGroup& other);
49
50         Array::Usage                                    m_usage;
51 };
52
53 SingleVertexArrayUsageGroup::SingleVertexArrayUsageGroup (Context& context, Array::Usage usage)
54         : TestCaseGroup (context, Array::usageTypeToString(usage).c_str(), Array::usageTypeToString(usage).c_str())
55         , m_usage               (usage)
56 {
57 }
58
59 SingleVertexArrayUsageGroup::~SingleVertexArrayUsageGroup (void)
60 {
61 }
62
63 template<class T>
64 static std::string typeToString (T t)
65 {
66         std::stringstream strm;
67         strm << t;
68         return strm.str();
69 }
70
71 void SingleVertexArrayUsageGroup::init (void)
72 {
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                                 const int                       stride  = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
84                                 const bool                      aligned = (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
85                                 const std::string       name    = "stride" + typeToString(stride) + "_" + Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_quads" + typeToString(counts[countNdx]);
86
87                                 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
88                                                                                                                                 Array::OUTPUTTYPE_VEC2,
89                                                                                                                                 Array::STORAGE_BUFFER,
90                                                                                                                                 m_usage,
91                                                                                                                                 2,
92                                                                                                                                 0,
93                                                                                                                                 stride,
94                                                                                                                                 false,
95                                                                                                                                 GLValue::getMinValue(inputTypes[inputTypeNdx]),
96                                                                                                                                 GLValue::getMaxValue(inputTypes[inputTypeNdx]));
97
98                                 MultiVertexArrayTest::Spec spec;
99                                 spec.primitive  = Array::PRIMITIVE_TRIANGLES;
100                                 spec.drawCount  = counts[countNdx];
101                                 spec.first              = 0;
102                                 spec.arrays.push_back(arraySpec);
103
104                                 if (aligned)
105                                         addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
106                         }
107                 }
108         }
109 }
110
111 class SingleVertexArrayUsageTests : public TestCaseGroup
112 {
113 public:
114                                                                         SingleVertexArrayUsageTests             (Context& context);
115         virtual                                                 ~SingleVertexArrayUsageTests    (void);
116
117         virtual void                                    init                                                    (void);
118
119 private:
120                                                                         SingleVertexArrayUsageTests             (const SingleVertexArrayUsageTests& other);
121         SingleVertexArrayUsageTests&    operator=                                               (const SingleVertexArrayUsageTests& other);
122 };
123
124 SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context)
125         : TestCaseGroup(context, "usages", "Single vertex atribute, usage")
126 {
127 }
128
129 SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void)
130 {
131 }
132
133 void SingleVertexArrayUsageTests::init (void)
134 {
135         // Test usage
136         Array::Usage            usages[]                = { Array::USAGE_STATIC_DRAW, Array::USAGE_STREAM_DRAW, Array::USAGE_DYNAMIC_DRAW, Array::USAGE_STATIC_COPY, Array::USAGE_STREAM_COPY, Array::USAGE_DYNAMIC_COPY, Array::USAGE_STATIC_READ, Array::USAGE_STREAM_READ, Array::USAGE_DYNAMIC_READ };
137         for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
138         {
139                 addChild(new SingleVertexArrayUsageGroup(m_context, usages[usageNdx]));
140         }
141 }
142
143 class SingleVertexArrayStrideGroup : public TestCaseGroup
144 {
145 public:
146                                                                         SingleVertexArrayStrideGroup    (Context& context, Array::InputType type);
147         virtual                                                 ~SingleVertexArrayStrideGroup   (void);
148
149         virtual void                                    init                                                    (void);
150
151 private:
152                                                                         SingleVertexArrayStrideGroup    (const SingleVertexArrayStrideGroup& other);
153         SingleVertexArrayStrideGroup&   operator=                                               (const SingleVertexArrayStrideGroup& other);
154
155         Array::InputType                                m_type;
156 };
157
158 SingleVertexArrayStrideGroup::SingleVertexArrayStrideGroup (Context& context, Array::InputType type)
159         : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
160         , m_type                (type)
161 {
162 }
163
164 SingleVertexArrayStrideGroup::~SingleVertexArrayStrideGroup (void)
165 {
166 }
167
168 void SingleVertexArrayStrideGroup::init (void)
169 {
170         Array::Storage          storages[]              = {Array::STORAGE_USER, Array::STORAGE_BUFFER};
171         int                                     counts[]                = {1, 256};
172         int                                     strides[]               = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
173
174         for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
175         {
176                 for (int componentCount = 2; componentCount < 5; componentCount++)
177                 {
178                         for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
179                         {
180                                 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
181                                 {
182                                         const bool      packed                  = m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
183                                         const int       stride                  = (strides[strideNdx] < 0) ? ((packed) ? (16) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
184                                         const int       alignment               = (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
185                                         const bool      bufferUnaligned = (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % alignment) != 0;
186
187                                         std::string name = Array::storageToString(storages[storageNdx]) + "_stride" + typeToString(stride) + "_components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]);
188
189                                         if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4)
190                                                 continue;
191
192                                         MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
193                                                                                                                                         Array::OUTPUTTYPE_VEC4,
194                                                                                                                                         storages[storageNdx],
195                                                                                                                                         Array::USAGE_DYNAMIC_DRAW,
196                                                                                                                                         componentCount,
197                                                                                                                                         0,
198                                                                                                                                         stride,
199                                                                                                                                         false,
200                                                                                                                                         GLValue::getMinValue(m_type),
201                                                                                                                                         GLValue::getMaxValue(m_type));
202
203                                         MultiVertexArrayTest::Spec spec;
204                                         spec.primitive  = Array::PRIMITIVE_TRIANGLES;
205                                         spec.drawCount  = counts[countNdx];
206                                         spec.first              = 0;
207                                         spec.arrays.push_back(arraySpec);
208
209                                         if (!bufferUnaligned)
210                                                 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
211                                 }
212                         }
213                 }
214         }
215 }
216
217 class SingleVertexArrayStrideTests : public TestCaseGroup
218 {
219 public:
220                                                                         SingleVertexArrayStrideTests    (Context& context);
221         virtual                                                 ~SingleVertexArrayStrideTests   (void);
222
223         virtual void                                    init                                                    (void);
224
225 private:
226                                                                         SingleVertexArrayStrideTests    (const SingleVertexArrayStrideTests& other);
227         SingleVertexArrayStrideTests&   operator=                                               (const SingleVertexArrayStrideTests& other);
228 };
229
230 SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context)
231         : TestCaseGroup(context, "strides", "Single stride vertex atribute")
232 {
233 }
234
235 SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void)
236 {
237 }
238
239 void SingleVertexArrayStrideTests::init (void)
240 {
241         Array::InputType        inputTypes[]    = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED, Array::INPUTTYPE_INT_2_10_10_10 };
242
243         for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
244         {
245                 addChild(new SingleVertexArrayStrideGroup(m_context, inputTypes[inputTypeNdx]));
246         }
247 }
248
249 class SingleVertexArrayFirstGroup : public TestCaseGroup
250 {
251 public:
252                                                                         SingleVertexArrayFirstGroup     (Context& context, Array::InputType type);
253         virtual                                                 ~SingleVertexArrayFirstGroup    (void);
254
255         virtual void                                    init                                                    (void);
256
257 private:
258                                                                         SingleVertexArrayFirstGroup     (const SingleVertexArrayFirstGroup& other);
259         SingleVertexArrayFirstGroup&    operator=                                               (const SingleVertexArrayFirstGroup& other);
260         Array::InputType                                m_type;
261 };
262
263 SingleVertexArrayFirstGroup::SingleVertexArrayFirstGroup (Context& context, Array::InputType type)
264         : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
265         , m_type                (type)
266 {
267 }
268
269 SingleVertexArrayFirstGroup::~SingleVertexArrayFirstGroup (void)
270 {
271 }
272
273 void SingleVertexArrayFirstGroup::init (void)
274 {
275         int                                     counts[]                = {5, 256};
276         int                                     firsts[]                = {6, 24};
277         int                                     offsets[]               = {1, 16, 17};
278         int                                     strides[]               = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
279
280         for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
281         {
282                 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
283                 {
284                         for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
285                         {
286                                 for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++)
287                                 {
288                                         const bool      packed                  = m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
289                                         const int       componentCount  = (packed) ? (4) : (2);
290                                         const int       stride                  = (strides[strideNdx] < 0) ? ((packed) ? (8) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
291                                         const int       alignment               = (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
292                                         const bool      aligned                 = ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
293                                         std::string name                        = "first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]);
294
295                                         MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
296                                                                                                                                         Array::OUTPUTTYPE_VEC2,
297                                                                                                                                         Array::STORAGE_BUFFER,
298                                                                                                                                         Array::USAGE_DYNAMIC_DRAW,
299                                                                                                                                         componentCount,
300                                                                                                                                         offsets[offsetNdx],
301                                                                                                                                         stride,
302                                                                                                                                         false,
303                                                                                                                                         GLValue::getMinValue(m_type),
304                                                                                                                                         GLValue::getMaxValue(m_type));
305
306                                         MultiVertexArrayTest::Spec spec;
307                                         spec.primitive  = Array::PRIMITIVE_TRIANGLES;
308                                         spec.drawCount  = counts[countNdx];
309                                         spec.first              = firsts[firstNdx];
310                                         spec.arrays.push_back(arraySpec);
311
312                                         if (aligned)
313                                                 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
314                                 }
315                         }
316                 }
317         }
318 }
319
320 class SingleVertexArrayFirstTests : public TestCaseGroup
321 {
322 public:
323                                                                         SingleVertexArrayFirstTests     (Context& context);
324         virtual                                                 ~SingleVertexArrayFirstTests    (void);
325
326         virtual void                                    init                                                    (void);
327
328 private:
329                                                                         SingleVertexArrayFirstTests     (const SingleVertexArrayFirstTests& other);
330         SingleVertexArrayFirstTests&    operator=                                               (const SingleVertexArrayFirstTests& other);
331 };
332
333 SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context)
334         : TestCaseGroup(context, "first", "Single vertex attribute, different first values to drawArrays")
335 {
336 }
337
338 SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void)
339 {
340 }
341
342 void SingleVertexArrayFirstTests::init (void)
343 {
344         // Test offset with different input types, component counts and storage, Usage(?)
345         Array::InputType        inputTypes[]    = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_INT_2_10_10_10 };
346
347         for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
348         {
349                 addChild(new SingleVertexArrayFirstGroup(m_context, inputTypes[inputTypeNdx]));
350         }
351 }
352
353 class SingleVertexArrayOffsetGroup : public TestCaseGroup
354 {
355 public:
356                                                                         SingleVertexArrayOffsetGroup    (Context& context, Array::InputType type);
357         virtual                                                 ~SingleVertexArrayOffsetGroup   (void);
358
359         virtual void                                    init                                                    (void);
360
361 private:
362                                                                         SingleVertexArrayOffsetGroup    (const SingleVertexArrayOffsetGroup& other);
363         SingleVertexArrayOffsetGroup&   operator=                                               (const SingleVertexArrayOffsetGroup& other);
364         Array::InputType                                m_type;
365 };
366
367 SingleVertexArrayOffsetGroup::SingleVertexArrayOffsetGroup (Context& context, Array::InputType type)
368         : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
369         , m_type                (type)
370 {
371 }
372
373 SingleVertexArrayOffsetGroup::~SingleVertexArrayOffsetGroup (void)
374 {
375 }
376
377 void SingleVertexArrayOffsetGroup::init (void)
378 {
379         int                                     counts[]                = {1, 256};
380         int                                     offsets[]               = {1, 4, 17, 32};
381         int                                     strides[]               = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
382
383         for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
384         {
385                 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
386                 {
387                         for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
388                         {
389                                 const bool                      packed                  = m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
390                                 const int                       componentCount  = (packed) ? (4) : (2);
391                                 const int                       stride                  = (strides[strideNdx] < 0 ? Array::inputTypeSize(m_type) * componentCount : strides[strideNdx]);
392                                 const int                       alignment               = (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
393                                 const bool                      aligned                 = ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
394                                 const std::string       name                    = "offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]);
395
396                                 MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
397                                                                                                                                 Array::OUTPUTTYPE_VEC2,
398                                                                                                                                 Array::STORAGE_BUFFER,
399                                                                                                                                 Array::USAGE_DYNAMIC_DRAW,
400                                                                                                                                 componentCount,
401                                                                                                                                 offsets[offsetNdx],
402                                                                                                                                 stride,
403                                                                                                                                 false,
404                                                                                                                                 GLValue::getMinValue(m_type),
405                                                                                                                                 GLValue::getMaxValue(m_type));
406
407                                 MultiVertexArrayTest::Spec spec;
408                                 spec.primitive  = Array::PRIMITIVE_TRIANGLES;
409                                 spec.drawCount  = counts[countNdx];
410                                 spec.first              = 0;
411                                 spec.arrays.push_back(arraySpec);
412
413                                 if (aligned)
414                                         addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
415                         }
416                 }
417         }
418 }
419
420 class SingleVertexArrayOffsetTests : public TestCaseGroup
421 {
422 public:
423                                                                         SingleVertexArrayOffsetTests    (Context& context);
424         virtual                                                 ~SingleVertexArrayOffsetTests   (void);
425
426         virtual void                                    init                                                    (void);
427
428 private:
429                                                                         SingleVertexArrayOffsetTests    (const SingleVertexArrayOffsetTests& other);
430         SingleVertexArrayOffsetTests&   operator=                                               (const SingleVertexArrayOffsetTests& other);
431 };
432
433 SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context)
434         : TestCaseGroup(context, "offset", "Single vertex atribute offset element")
435 {
436 }
437
438 SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void)
439 {
440 }
441
442 void SingleVertexArrayOffsetTests::init (void)
443 {
444         // Test offset with different input types, component counts and storage, Usage(?)
445         Array::InputType        inputTypes[]    = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_INT_2_10_10_10 };
446
447         for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
448         {
449                 addChild(new SingleVertexArrayOffsetGroup(m_context, inputTypes[inputTypeNdx]));
450         }
451 }
452
453 class SingleVertexArrayNormalizeGroup : public TestCaseGroup
454 {
455 public:
456                                                                                 SingleVertexArrayNormalizeGroup         (Context& context, Array::InputType type);
457         virtual                                                         ~SingleVertexArrayNormalizeGroup        (void);
458
459         virtual void                                            init                                                            (void);
460
461 private:
462                                                                                 SingleVertexArrayNormalizeGroup         (const SingleVertexArrayNormalizeGroup& other);
463         SingleVertexArrayNormalizeGroup&        operator=                                                       (const SingleVertexArrayNormalizeGroup& other);
464         Array::InputType                                        m_type;
465 };
466
467 SingleVertexArrayNormalizeGroup::SingleVertexArrayNormalizeGroup (Context& context, Array::InputType type)
468         : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
469         , m_type                (type)
470 {
471 }
472
473 SingleVertexArrayNormalizeGroup::~SingleVertexArrayNormalizeGroup (void)
474 {
475 }
476
477 void SingleVertexArrayNormalizeGroup::init (void)
478 {
479         int                                     counts[]                = {1, 256};
480
481         for (int componentCount = 2; componentCount < 5; componentCount++)
482         {
483                 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
484                 {
485                         if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4)
486                                 continue;
487
488                         std::string name = "components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]);
489
490                         MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
491                                                                                                                         Array::OUTPUTTYPE_VEC4,
492                                                                                                                         Array::STORAGE_USER,
493                                                                                                                         Array::USAGE_DYNAMIC_DRAW,
494                                                                                                                         componentCount,
495                                                                                                                         0,
496                                                                                                                         0,
497                                                                                                                         true,
498                                                                                                                         GLValue::getMinValue(m_type),
499                                                                                                                         GLValue::getMaxValue(m_type));
500
501                         MultiVertexArrayTest::Spec spec;
502                         spec.primitive  = Array::PRIMITIVE_TRIANGLES;
503                         spec.drawCount  = counts[countNdx];
504                         spec.first              = 0;
505                         spec.arrays.push_back(arraySpec);
506
507                         addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
508                 }
509         }
510 }
511
512 class SingleVertexArrayNormalizeTests : public TestCaseGroup
513 {
514 public:
515                                                                                 SingleVertexArrayNormalizeTests         (Context& context);
516         virtual                                                         ~SingleVertexArrayNormalizeTests        (void);
517
518         virtual void                                            init                                                            (void);
519
520 private:
521                                                                                 SingleVertexArrayNormalizeTests         (const SingleVertexArrayNormalizeTests& other);
522         SingleVertexArrayNormalizeTests&        operator=                                                       (const SingleVertexArrayNormalizeTests& other);
523 };
524
525 SingleVertexArrayNormalizeTests::SingleVertexArrayNormalizeTests (Context& context)
526         : TestCaseGroup(context, "normalize", "Single normalize vertex atribute")
527 {
528 }
529
530 SingleVertexArrayNormalizeTests::~SingleVertexArrayNormalizeTests (void)
531 {
532 }
533
534 void SingleVertexArrayNormalizeTests::init (void)
535 {
536         // Test normalization with different input types, component counts and storage
537         Array::InputType        inputTypes[]    = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_UNSIGNED_INT, Array::INPUTTYPE_INT, Array::INPUTTYPE_HALF , Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10, Array::INPUTTYPE_INT_2_10_10_10 };
538
539         for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
540         {
541                 addChild(new SingleVertexArrayNormalizeGroup(m_context, inputTypes[inputTypeNdx]));
542         }
543 }
544
545 class SingleVertexArrayOutputTypeGroup : public TestCaseGroup
546 {
547 public:
548                                                                                 SingleVertexArrayOutputTypeGroup        (Context& context, Array::InputType type);
549         virtual                                                         ~SingleVertexArrayOutputTypeGroup       (void);
550
551         virtual void                                            init                                                            (void);
552
553 private:
554                                                                                 SingleVertexArrayOutputTypeGroup        (const SingleVertexArrayOutputTypeGroup& other);
555         SingleVertexArrayOutputTypeGroup&       operator=                                                       (const SingleVertexArrayOutputTypeGroup& other);
556         Array::InputType                                        m_type;
557 };
558
559 SingleVertexArrayOutputTypeGroup::SingleVertexArrayOutputTypeGroup (Context& context, Array::InputType type)
560         : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
561         , m_type                (type)
562 {
563 }
564
565 SingleVertexArrayOutputTypeGroup::~SingleVertexArrayOutputTypeGroup (void)
566 {
567 }
568
569 void SingleVertexArrayOutputTypeGroup::init (void)
570 {
571         Array::OutputType       outputTypes[]   = {Array::OUTPUTTYPE_VEC2, Array::OUTPUTTYPE_VEC3, Array::OUTPUTTYPE_VEC4, Array::OUTPUTTYPE_IVEC2, Array::OUTPUTTYPE_IVEC3, Array::OUTPUTTYPE_IVEC4, Array::OUTPUTTYPE_UVEC2, Array::OUTPUTTYPE_UVEC3, Array::OUTPUTTYPE_UVEC4 };
572         Array::Storage          storages[]              = {Array::STORAGE_USER};
573         int                                     counts[]                = {1, 256};
574
575         for (int outputTypeNdx = 0; outputTypeNdx < DE_LENGTH_OF_ARRAY(outputTypes); outputTypeNdx++)
576         {
577                 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
578                 {
579                         for (int componentCount = 2; componentCount < 5; componentCount++)
580                         {
581                                 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
582                                 {
583                                         std::string name = "components" + typeToString(componentCount) + "_" + Array::outputTypeToString(outputTypes[outputTypeNdx]) + "_quads" + typeToString(counts[countNdx]);
584
585                                         const bool inputIsSignedInteger         = m_type == Array::INPUTTYPE_INT || m_type == Array::INPUTTYPE_SHORT || m_type == Array::INPUTTYPE_BYTE;
586                                         const bool inputIsUnignedInteger        = m_type == Array::INPUTTYPE_UNSIGNED_INT || m_type == Array::INPUTTYPE_UNSIGNED_SHORT || m_type == Array::INPUTTYPE_UNSIGNED_BYTE;
587                                         const bool outputIsSignedInteger        = outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC2 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC3 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC4;
588                                         const bool outputIsUnsignedInteger      = outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC2 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC3 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC4;
589
590                                         // If input type is float type and output type is int type skip
591                                         if ((m_type == Array::INPUTTYPE_FLOAT ||  m_type == Array::INPUTTYPE_HALF || m_type == Array::INPUTTYPE_FIXED) && (outputTypes[outputTypeNdx] >= Array::OUTPUTTYPE_INT))
592                                                 continue;
593
594                                         if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && (outputTypes[outputTypeNdx] >= Array::OUTPUTTYPE_INT))
595                                                 continue;
596
597                                         if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4)
598                                                 continue;
599
600                                         // Loading signed data as unsigned causes undefined values and vice versa
601                                         if (inputIsSignedInteger && outputIsUnsignedInteger)
602                                                 continue;
603                                         if (inputIsUnignedInteger && outputIsSignedInteger)
604                                                 continue;
605
606                                         MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
607                                                                                                                                         outputTypes[outputTypeNdx],
608                                                                                                                                         storages[storageNdx],
609                                                                                                                                         Array::USAGE_DYNAMIC_DRAW,
610                                                                                                                                         componentCount,
611                                                                                                                                         0,
612                                                                                                                                         0,
613                                                                                                                                         false,
614                                                                                                                                         GLValue::getMinValue(m_type),
615                                                                                                                                         GLValue::getMaxValue(m_type));
616
617                                         MultiVertexArrayTest::Spec spec;
618                                         spec.primitive  = Array::PRIMITIVE_TRIANGLES;
619                                         spec.drawCount  = counts[countNdx];
620                                         spec.first              = 0;
621                                         spec.arrays.push_back(arraySpec);
622
623                                         addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
624                                 }
625                         }
626                 }
627         }
628 }
629
630 class SingleVertexArrayOutputTypeTests : public TestCaseGroup
631 {
632 public:
633                                                                                 SingleVertexArrayOutputTypeTests        (Context& context);
634         virtual                                                         ~SingleVertexArrayOutputTypeTests       (void);
635
636         virtual void                                            init                                                            (void);
637
638 private:
639                                                                                 SingleVertexArrayOutputTypeTests        (const SingleVertexArrayOutputTypeTests& other);
640         SingleVertexArrayOutputTypeTests&       operator=                                                       (const SingleVertexArrayOutputTypeTests& other);
641 };
642
643 SingleVertexArrayOutputTypeTests::SingleVertexArrayOutputTypeTests (Context& context)
644         : TestCaseGroup(context, "output_types", "Single output type vertex atribute")
645 {
646 }
647
648 SingleVertexArrayOutputTypeTests::~SingleVertexArrayOutputTypeTests (void)
649 {
650 }
651
652 void SingleVertexArrayOutputTypeTests::init (void)
653 {
654         // Test output types with different input types, component counts and storage, Usage?, Precision?, float?
655         Array::InputType        inputTypes[]    = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_UNSIGNED_INT, Array::INPUTTYPE_INT, Array::INPUTTYPE_HALF, Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10, Array::INPUTTYPE_INT_2_10_10_10 };
656
657         for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
658         {
659                 addChild(new SingleVertexArrayOutputTypeGroup(m_context, inputTypes[inputTypeNdx]));
660         }
661 }
662
663
664 class SingleVertexArrayTestGroup : public TestCaseGroup
665 {
666 public:
667                                                                         SingleVertexArrayTestGroup      (Context& context);
668         virtual                                                 ~SingleVertexArrayTestGroup     (void);
669
670         virtual void                                    init                                            (void);
671
672 private:
673                                                                         SingleVertexArrayTestGroup      (const SingleVertexArrayTestGroup& other);
674         SingleVertexArrayTestGroup&             operator=                                       (const SingleVertexArrayTestGroup& other);
675 };
676
677 SingleVertexArrayTestGroup::SingleVertexArrayTestGroup (Context& context)
678         : TestCaseGroup(context, "single_attribute", "Single vertex atribute")
679 {
680 }
681
682 SingleVertexArrayTestGroup::~SingleVertexArrayTestGroup (void)
683 {
684 }
685
686 void SingleVertexArrayTestGroup::init (void)
687 {
688         addChild(new SingleVertexArrayStrideTests(m_context));
689         addChild(new SingleVertexArrayNormalizeTests(m_context));
690         addChild(new SingleVertexArrayOutputTypeTests(m_context));
691         addChild(new SingleVertexArrayUsageTests(m_context));
692         addChild(new SingleVertexArrayOffsetTests(m_context));
693         addChild(new SingleVertexArrayFirstTests(m_context));
694 }
695
696 class MultiVertexArrayCountTests : public TestCaseGroup
697 {
698 public:
699                                                                         MultiVertexArrayCountTests      (Context& context);
700         virtual                                                 ~MultiVertexArrayCountTests     (void);
701
702         virtual void                                    init                                            (void);
703
704 private:
705                                                                         MultiVertexArrayCountTests      (const MultiVertexArrayCountTests& other);
706         MultiVertexArrayCountTests&             operator=                                       (const MultiVertexArrayCountTests& other);
707
708         std::string                                             getTestName                                     (const MultiVertexArrayTest::Spec& spec);
709 };
710
711 MultiVertexArrayCountTests::MultiVertexArrayCountTests (Context& context)
712         : TestCaseGroup(context, "attribute_count", "Attribute counts")
713 {
714 }
715
716 MultiVertexArrayCountTests::~MultiVertexArrayCountTests (void)
717 {
718 }
719
720 std::string MultiVertexArrayCountTests::getTestName (const MultiVertexArrayTest::Spec& spec)
721 {
722         std::stringstream name;
723         name
724                 << spec.arrays.size();
725
726         return name.str();
727 }
728
729 void MultiVertexArrayCountTests::init (void)
730 {
731         // Test attribute counts
732         int arrayCounts[] = {2, 3, 4, 5, 6, 7, 8};
733
734         for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
735         {
736                 MultiVertexArrayTest::Spec spec;
737
738                 spec.primitive  = Array::PRIMITIVE_TRIANGLES;
739                 spec.drawCount  = 256;
740                 spec.first              = 0;
741
742                 for (int arrayNdx = 0; arrayNdx < arrayCounts[arrayCountNdx]; arrayNdx++)
743                 {
744                         MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
745                                                                                                                         Array::OUTPUTTYPE_VEC2,
746                                                                                                                         Array::STORAGE_USER,
747                                                                                                                         Array::USAGE_DYNAMIC_DRAW,
748                                                                                                                         2,
749                                                                                                                         0,
750                                                                                                                         0,
751                                                                                                                         false,
752                                                                                                                         GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
753                                                                                                                         GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
754
755                         spec.arrays.push_back(arraySpec);
756                 }
757
758                 std::string name = getTestName(spec);
759                 std::string desc = getTestName(spec);
760
761                 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
762         }
763 }
764
765 class MultiVertexArrayStorageTests : public TestCaseGroup
766 {
767 public:
768                                                                         MultiVertexArrayStorageTests    (Context& context);
769         virtual                                                 ~MultiVertexArrayStorageTests   (void);
770
771         virtual void                                    init                                                    (void);
772
773 private:
774                                                                         MultiVertexArrayStorageTests    (const MultiVertexArrayStorageTests& other);
775         MultiVertexArrayStorageTests&   operator=                                               (const MultiVertexArrayStorageTests& other);
776
777         void                                                    addStorageCases                                 (MultiVertexArrayTest::Spec spec, int depth);
778         std::string                                             getTestName                                             (const MultiVertexArrayTest::Spec& spec);
779 };
780
781 MultiVertexArrayStorageTests::MultiVertexArrayStorageTests (Context& context)
782         : TestCaseGroup(context, "storage", "Attribute storages")
783 {
784 }
785
786 MultiVertexArrayStorageTests::~MultiVertexArrayStorageTests (void)
787 {
788 }
789
790 std::string MultiVertexArrayStorageTests::getTestName (const MultiVertexArrayTest::Spec& spec)
791 {
792         std::stringstream name;
793         name
794                 << spec.arrays.size();
795
796         for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
797         {
798                 name
799                         << "_"
800                         << Array::storageToString(spec.arrays[arrayNdx].storage);
801         }
802
803         return name.str();
804 }
805
806 void MultiVertexArrayStorageTests::addStorageCases (MultiVertexArrayTest::Spec spec, int depth)
807 {
808         if (depth == 0)
809         {
810                 // Skip trivial case, used elsewhere
811                 bool ok = false;
812                 for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
813                 {
814                         if (spec.arrays[arrayNdx].storage != Array::STORAGE_USER)
815                         {
816                                 ok = true;
817                                 break;
818                         }
819                 }
820
821                 if (!ok)
822                         return;
823
824                 std::string name = getTestName(spec);
825                 std::string desc = getTestName(spec);
826
827                 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
828                 return;
829         }
830
831         Array::Storage storages[] = {Array::STORAGE_USER, Array::STORAGE_BUFFER};
832         for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
833         {
834                 MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
835                                                                                                                 Array::OUTPUTTYPE_VEC2,
836                                                                                                                 storages[storageNdx],
837                                                                                                                 Array::USAGE_DYNAMIC_DRAW,
838                                                                                                                 2,
839                                                                                                                 0,
840                                                                                                                 0,
841                                                                                                                 false,
842                                                                                                                 GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
843                                                                                                                 GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
844
845                 MultiVertexArrayTest::Spec _spec = spec;
846                 _spec.arrays.push_back(arraySpec);
847                 addStorageCases(_spec, depth-1);
848         }
849 }
850
851
852 void MultiVertexArrayStorageTests::init (void)
853 {
854         // Test different storages
855         int arrayCounts[] = {3};
856
857         MultiVertexArrayTest::Spec spec;
858
859         spec.primitive  = Array::PRIMITIVE_TRIANGLES;
860         spec.drawCount  = 256;
861         spec.first              = 0;
862
863         for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
864                 addStorageCases(spec, arrayCounts[arrayCountNdx]);
865 }
866
867 class MultiVertexArrayStrideTests : public TestCaseGroup
868 {
869 public:
870                                                                         MultiVertexArrayStrideTests             (Context& context);
871         virtual                                                 ~MultiVertexArrayStrideTests    (void);
872
873         virtual void                                    init                                                    (void);
874
875 private:
876                                                                         MultiVertexArrayStrideTests             (const MultiVertexArrayStrideTests& other);
877         MultiVertexArrayStrideTests&    operator=                                               (const MultiVertexArrayStrideTests& other);
878
879         void                                                    addStrideCases                                  (MultiVertexArrayTest::Spec spec, int depth);
880         std::string                                             getTestName                                             (const MultiVertexArrayTest::Spec& spec);
881 };
882
883 MultiVertexArrayStrideTests::MultiVertexArrayStrideTests (Context& context)
884         : TestCaseGroup(context, "stride", "Strides")
885 {
886 }
887
888 MultiVertexArrayStrideTests::~MultiVertexArrayStrideTests (void)
889 {
890 }
891
892 std::string MultiVertexArrayStrideTests::getTestName (const MultiVertexArrayTest::Spec& spec)
893 {
894         std::stringstream name;
895
896         name
897                 << spec.arrays.size();
898
899         for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
900         {
901                 name
902                         << "_"
903                         << Array::inputTypeToString(spec.arrays[arrayNdx].inputType)
904                         << spec.arrays[arrayNdx].componentCount << "_"
905                         << spec.arrays[arrayNdx].stride;
906         }
907
908         return name.str();
909 }
910
911 void MultiVertexArrayStrideTests::init (void)
912 {
913         // Test different strides, with multiple arrays, input types??
914         int arrayCounts[] = {3};
915
916         MultiVertexArrayTest::Spec spec;
917
918         spec.primitive  = Array::PRIMITIVE_TRIANGLES;
919         spec.drawCount  = 256;
920         spec.first              = 0;
921
922         for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
923                 addStrideCases(spec, arrayCounts[arrayCountNdx]);
924 }
925
926 void MultiVertexArrayStrideTests::addStrideCases (MultiVertexArrayTest::Spec spec, int depth)
927 {
928         if (depth == 0)
929         {
930                 std::string name = getTestName(spec);
931                 std::string desc = getTestName(spec);
932                 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
933                 return;
934         }
935
936         int strides[]   = {0, -1, 17, 32};
937
938         for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
939         {
940                 const int componentCount = 2;
941                 MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT,
942                                                                                                                 Array::OUTPUTTYPE_VEC2,
943                                                                                                                 Array::STORAGE_USER,
944                                                                                                                 Array::USAGE_DYNAMIC_DRAW,
945                                                                                                                 componentCount,
946                                                                                                                 0,
947                                                                                                                 (strides[strideNdx] >= 0 ? strides[strideNdx] : componentCount * Array::inputTypeSize(Array::INPUTTYPE_FLOAT)),
948                                                                                                                 false,
949                                                                                                                 GLValue::getMinValue(Array::INPUTTYPE_FLOAT),
950                                                                                                                 GLValue::getMaxValue(Array::INPUTTYPE_FLOAT));
951
952                 MultiVertexArrayTest::Spec _spec = spec;
953                 _spec.arrays.push_back(arraySpec);
954                 addStrideCases(_spec, depth-1);
955         }
956 }
957
958 class MultiVertexArrayOutputTests : public TestCaseGroup
959 {
960 public:
961                                                                                 MultiVertexArrayOutputTests             (Context& context);
962         virtual                                                         ~MultiVertexArrayOutputTests    (void);
963
964         virtual void                                            init                                                            (void);
965
966 private:
967                                                                                 MultiVertexArrayOutputTests             (const MultiVertexArrayOutputTests& other);
968         MultiVertexArrayOutputTests&    operator=                                                       (const MultiVertexArrayOutputTests& other);
969
970         void                                                            addInputTypeCases                                       (MultiVertexArrayTest::Spec spec, int depth);
971         std::string                                                     getTestName                                                     (const MultiVertexArrayTest::Spec& spec);
972 };
973
974 MultiVertexArrayOutputTests::MultiVertexArrayOutputTests (Context& context)
975         : TestCaseGroup(context, "input_types", "input types")
976 {
977 }
978
979 MultiVertexArrayOutputTests::~MultiVertexArrayOutputTests (void)
980 {
981 }
982
983 std::string MultiVertexArrayOutputTests::getTestName (const MultiVertexArrayTest::Spec& spec)
984 {
985         std::stringstream name;
986
987         name
988                 << spec.arrays.size();
989
990         for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++)
991         {
992                 name
993                         << "_"
994                         << Array::inputTypeToString(spec.arrays[arrayNdx].inputType)
995                         << spec.arrays[arrayNdx].componentCount << "_"
996                         << Array::outputTypeToString(spec.arrays[arrayNdx].outputType);
997         }
998
999         return name.str();
1000 }
1001
1002 void MultiVertexArrayOutputTests::init (void)
1003 {
1004         // Test different input types, with multiple arrays
1005         int arrayCounts[] = {3};
1006
1007         MultiVertexArrayTest::Spec spec;
1008
1009         spec.primitive  = Array::PRIMITIVE_TRIANGLES;
1010         spec.drawCount  = 256;
1011         spec.first              = 0;
1012
1013         for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++)
1014                 addInputTypeCases(spec, arrayCounts[arrayCountNdx]);
1015 }
1016
1017 void MultiVertexArrayOutputTests::addInputTypeCases (MultiVertexArrayTest::Spec spec, int depth)
1018 {
1019         if (depth == 0)
1020         {
1021                 std::string name = getTestName(spec);
1022                 std::string desc = getTestName(spec);
1023                 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str()));
1024                 return;
1025         }
1026
1027         Array::InputType inputTypes[] = {Array::INPUTTYPE_FIXED, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT};
1028         for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
1029         {
1030                 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
1031                                                                                                                 Array::OUTPUTTYPE_VEC2,
1032                                                                                                                 Array::STORAGE_USER,
1033                                                                                                                 Array::USAGE_DYNAMIC_DRAW,
1034                                                                                                                 2,
1035                                                                                                                 0,
1036                                                                                                                 0,
1037                                                                                                                 false,
1038                                                                                                                 GLValue::getMinValue(inputTypes[inputTypeNdx]),
1039                                                                                                                 GLValue::getMaxValue(inputTypes[inputTypeNdx]));
1040
1041                 MultiVertexArrayTest::Spec _spec = spec;
1042                 _spec.arrays.push_back(arraySpec);
1043                 addInputTypeCases(_spec, depth-1);
1044         }
1045 }
1046
1047 class MultiVertexArrayTestGroup : public TestCaseGroup
1048 {
1049 public:
1050                                                                         MultiVertexArrayTestGroup       (Context& context);
1051         virtual                                                 ~MultiVertexArrayTestGroup      (void);
1052
1053         virtual void                                    init                                            (void);
1054
1055 private:
1056                                                                         MultiVertexArrayTestGroup       (const MultiVertexArrayTestGroup& other);
1057         MultiVertexArrayTestGroup&              operator=                                       (const MultiVertexArrayTestGroup& other);
1058 };
1059
1060 MultiVertexArrayTestGroup::MultiVertexArrayTestGroup (Context& context)
1061         : TestCaseGroup(context, "multiple_attributes", "Multiple vertex atributes")
1062 {
1063 }
1064
1065 MultiVertexArrayTestGroup::~MultiVertexArrayTestGroup (void)
1066 {
1067 }
1068
1069 void MultiVertexArrayTestGroup::init (void)
1070 {
1071         addChild(new MultiVertexArrayCountTests(m_context));
1072         addChild(new MultiVertexArrayStorageTests(m_context));
1073         addChild(new MultiVertexArrayStrideTests(m_context));
1074         addChild(new MultiVertexArrayOutputTests(m_context));
1075 }
1076
1077 VertexArrayTestGroup::VertexArrayTestGroup (Context& context)
1078         : TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests")
1079 {
1080 }
1081
1082 VertexArrayTestGroup::~VertexArrayTestGroup (void)
1083 {
1084 }
1085
1086 void VertexArrayTestGroup::init (void)
1087 {
1088         addChild(new SingleVertexArrayTestGroup(m_context));
1089         addChild(new MultiVertexArrayTestGroup(m_context));
1090 }
1091
1092 } // Functional
1093 } // gles3
1094 } // deqp