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