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