xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fVertexArrayTest.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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