xref: /aosp_15_r20/external/deqp/modules/gles2/stress/es2sVertexArrayTests.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 unaligned access stress tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es2sVertexArrayTests.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 Stress
36 {
37 namespace
38 {
39 
40 template <class T>
typeToString(T t)41 static std::string typeToString(T t)
42 {
43     std::stringstream strm;
44     strm << t;
45     return strm.str();
46 }
47 
48 class SingleVertexArrayUsageTests : public TestCaseGroup
49 {
50 public:
51     SingleVertexArrayUsageTests(Context &context);
52     virtual ~SingleVertexArrayUsageTests(void);
53 
54     virtual void init(void);
55 
56 private:
57     SingleVertexArrayUsageTests(const SingleVertexArrayUsageTests &other);
58     SingleVertexArrayUsageTests &operator=(const SingleVertexArrayUsageTests &other);
59 };
60 
SingleVertexArrayUsageTests(Context & context)61 SingleVertexArrayUsageTests::SingleVertexArrayUsageTests(Context &context)
62     : TestCaseGroup(context, "usages", "Single vertex atribute, usage")
63 {
64 }
65 
~SingleVertexArrayUsageTests(void)66 SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests(void)
67 {
68 }
69 
init(void)70 void SingleVertexArrayUsageTests::init(void)
71 {
72     // Test usage
73     Array::Usage usages[]         = {Array::USAGE_STATIC_DRAW, Array::USAGE_STREAM_DRAW, Array::USAGE_DYNAMIC_DRAW};
74     int counts[]                  = {1, 256};
75     int strides[]                 = {17};
76     Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_SHORT,
77                                      Array::INPUTTYPE_BYTE};
78 
79     for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
80     {
81         for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
82         {
83             for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
84             {
85                 for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
86                 {
87                     const int componentCount = 2;
88                     const int stride =
89                         (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * componentCount :
90                                                   strides[strideNdx]);
91                     const bool aligned = (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
92                     MultiVertexArrayTest::Spec::ArraySpec arraySpec(
93                         inputTypes[inputTypeNdx], Array::OUTPUTTYPE_VEC2, Array::STORAGE_BUFFER, usages[usageNdx],
94                         componentCount, 0, stride, false, GLValue::getMinValue(inputTypes[inputTypeNdx]),
95                         GLValue::getMaxValue(inputTypes[inputTypeNdx]));
96 
97                     MultiVertexArrayTest::Spec spec;
98                     spec.primitive = Array::PRIMITIVE_TRIANGLES;
99                     spec.drawCount = counts[countNdx];
100                     spec.first     = 0;
101                     spec.arrays.push_back(arraySpec);
102 
103                     std::string name = spec.getName();
104 
105                     if (!aligned)
106                         addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(),
107                                                           name.c_str()));
108                 }
109             }
110         }
111     }
112 }
113 
114 class SingleVertexArrayStrideTests : public TestCaseGroup
115 {
116 public:
117     SingleVertexArrayStrideTests(Context &context);
118     virtual ~SingleVertexArrayStrideTests(void);
119 
120     virtual void init(void);
121 
122 private:
123     SingleVertexArrayStrideTests(const SingleVertexArrayStrideTests &other);
124     SingleVertexArrayStrideTests &operator=(const SingleVertexArrayStrideTests &other);
125 };
126 
SingleVertexArrayStrideTests(Context & context)127 SingleVertexArrayStrideTests::SingleVertexArrayStrideTests(Context &context)
128     : TestCaseGroup(context, "strides", "Single stride vertex atribute")
129 {
130 }
131 
~SingleVertexArrayStrideTests(void)132 SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests(void)
133 {
134 }
135 
init(void)136 void SingleVertexArrayStrideTests::init(void)
137 {
138     // Test strides with different input types, component counts and storage, Usage(?)
139     Array::InputType inputTypes[] = {
140         Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE,
141         /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED};
142     Array::Storage storages[] = {Array::STORAGE_BUFFER};
143     int counts[]              = {1, 256};
144     int strides[]             = {17};
145 
146     for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
147     {
148         for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
149         {
150             for (int componentCount = 2; componentCount < 5; componentCount++)
151             {
152                 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
153                 {
154                     for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
155                     {
156                         const int stride =
157                             (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * componentCount :
158                                                       strides[strideNdx]);
159                         const bool bufferUnaligned = (storages[storageNdx] == Array::STORAGE_BUFFER) &&
160                                                      (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) != 0;
161 
162                         MultiVertexArrayTest::Spec::ArraySpec arraySpec(
163                             inputTypes[inputTypeNdx], Array::OUTPUTTYPE_VEC4, storages[storageNdx],
164                             Array::USAGE_DYNAMIC_DRAW, componentCount, 0, stride, false,
165                             GLValue::getMinValue(inputTypes[inputTypeNdx]),
166                             GLValue::getMaxValue(inputTypes[inputTypeNdx]));
167 
168                         MultiVertexArrayTest::Spec spec;
169                         spec.primitive = Array::PRIMITIVE_TRIANGLES;
170                         spec.drawCount = counts[countNdx];
171                         spec.first     = 0;
172                         spec.arrays.push_back(arraySpec);
173 
174                         std::string name = spec.getName();
175                         if (bufferUnaligned)
176                             addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec,
177                                                               name.c_str(), name.c_str()));
178                     }
179                 }
180             }
181         }
182     }
183 }
184 
185 class SingleVertexArrayFirstTests : public TestCaseGroup
186 {
187 public:
188     SingleVertexArrayFirstTests(Context &context);
189     virtual ~SingleVertexArrayFirstTests(void);
190 
191     virtual void init(void);
192 
193 private:
194     SingleVertexArrayFirstTests(const SingleVertexArrayFirstTests &other);
195     SingleVertexArrayFirstTests &operator=(const SingleVertexArrayFirstTests &other);
196 };
197 
SingleVertexArrayFirstTests(Context & context)198 SingleVertexArrayFirstTests::SingleVertexArrayFirstTests(Context &context)
199     : TestCaseGroup(context, "first", "Single vertex atribute different first values")
200 {
201 }
202 
~SingleVertexArrayFirstTests(void)203 SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests(void)
204 {
205 }
206 
init(void)207 void SingleVertexArrayFirstTests::init(void)
208 {
209     // Test strides with different input types, component counts and storage, Usage(?)
210     Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_FIXED};
211     int counts[]                  = {5, 256};
212     int firsts[]                  = {6, 24};
213     int offsets[]                 = {1, 17};
214     int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
215 
216     for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
217     {
218         for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
219         {
220             for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
221             {
222                 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
223                 {
224                     for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++)
225                     {
226                         const int stride =
227                             (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 :
228                                                       strides[strideNdx]);
229                         const bool aligned = ((stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0) &&
230                                              (offsets[offsetNdx] % Array::inputTypeSize(inputTypes[inputTypeNdx]) == 0);
231 
232                         MultiVertexArrayTest::Spec::ArraySpec arraySpec(
233                             inputTypes[inputTypeNdx], Array::OUTPUTTYPE_VEC2, Array::STORAGE_BUFFER,
234                             Array::USAGE_DYNAMIC_DRAW, 2, offsets[offsetNdx], stride, false,
235                             GLValue::getMinValue(inputTypes[inputTypeNdx]),
236                             GLValue::getMaxValue(inputTypes[inputTypeNdx]));
237 
238                         MultiVertexArrayTest::Spec spec;
239                         spec.primitive = Array::PRIMITIVE_TRIANGLES;
240                         spec.drawCount = counts[countNdx];
241                         spec.first     = firsts[firstNdx];
242                         spec.arrays.push_back(arraySpec);
243 
244                         std::string name = Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_first" +
245                                            typeToString(firsts[firstNdx]) + "_offset" +
246                                            typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) +
247                                            "_quads" + typeToString(counts[countNdx]);
248                         if (!aligned)
249                             addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec,
250                                                               name.c_str(), name.c_str()));
251                     }
252                 }
253             }
254         }
255     }
256 }
257 
258 class SingleVertexArrayOffsetTests : public TestCaseGroup
259 {
260 public:
261     SingleVertexArrayOffsetTests(Context &context);
262     virtual ~SingleVertexArrayOffsetTests(void);
263 
264     virtual void init(void);
265 
266 private:
267     SingleVertexArrayOffsetTests(const SingleVertexArrayOffsetTests &other);
268     SingleVertexArrayOffsetTests &operator=(const SingleVertexArrayOffsetTests &other);
269 };
270 
SingleVertexArrayOffsetTests(Context & context)271 SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests(Context &context)
272     : TestCaseGroup(context, "offset", "Single vertex atribute offset element")
273 {
274 }
275 
~SingleVertexArrayOffsetTests(void)276 SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests(void)
277 {
278 }
279 
init(void)280 void SingleVertexArrayOffsetTests::init(void)
281 {
282     // Test strides with different input types, component counts and storage, Usage(?)
283     Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_FIXED};
284     int counts[]                  = {1, 256};
285     int offsets[]                 = {1, 4, 17, 32};
286     int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
287 
288     for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
289     {
290         for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
291         {
292             for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
293             {
294                 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
295                 {
296                     const int stride   = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 :
297                                                                    strides[strideNdx]);
298                     const bool aligned = ((stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0) &&
299                                          ((offsets[offsetNdx] % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0);
300 
301                     MultiVertexArrayTest::Spec::ArraySpec arraySpec(
302                         inputTypes[inputTypeNdx], Array::OUTPUTTYPE_VEC2, Array::STORAGE_BUFFER,
303                         Array::USAGE_DYNAMIC_DRAW, 2, offsets[offsetNdx], stride, false,
304                         GLValue::getMinValue(inputTypes[inputTypeNdx]), GLValue::getMaxValue(inputTypes[inputTypeNdx]));
305 
306                     MultiVertexArrayTest::Spec spec;
307                     spec.primitive = Array::PRIMITIVE_TRIANGLES;
308                     spec.drawCount = counts[countNdx];
309                     spec.first     = 0;
310                     spec.arrays.push_back(arraySpec);
311 
312                     std::string name = spec.getName();
313                     if (!aligned)
314                         addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(),
315                                                           name.c_str()));
316                 }
317             }
318         }
319     }
320 }
321 
322 } // namespace
323 
VertexArrayTests(Context & context)324 VertexArrayTests::VertexArrayTests(Context &context)
325     : TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests")
326 {
327 }
328 
~VertexArrayTests(void)329 VertexArrayTests::~VertexArrayTests(void)
330 {
331 }
332 
init(void)333 void VertexArrayTests::init(void)
334 {
335     tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(m_testCtx, "single_attribute", "Single attribute");
336     addChild(group);
337 
338     // .single_attribute
339     {
340         group->addChild(new SingleVertexArrayStrideTests(m_context));
341         group->addChild(new SingleVertexArrayUsageTests(m_context));
342         group->addChild(new SingleVertexArrayOffsetTests(m_context));
343         group->addChild(new SingleVertexArrayFirstTests(m_context));
344     }
345 }
346 
347 } // namespace Stress
348 } // namespace gles2
349 } // namespace deqp
350