1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 3.0 Module
3e5c31af7Sopenharmony_ci * -------------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Vertex array and buffer unaligned access stress tests
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "es3sVertexArrayTests.hpp"
25e5c31af7Sopenharmony_ci#include "glsVertexArrayTests.hpp"
26e5c31af7Sopenharmony_ci
27e5c31af7Sopenharmony_ci#include <sstream>
28e5c31af7Sopenharmony_ci
29e5c31af7Sopenharmony_ciusing namespace deqp::gls;
30e5c31af7Sopenharmony_ci
31e5c31af7Sopenharmony_cinamespace deqp
32e5c31af7Sopenharmony_ci{
33e5c31af7Sopenharmony_cinamespace gles3
34e5c31af7Sopenharmony_ci{
35e5c31af7Sopenharmony_cinamespace Stress
36e5c31af7Sopenharmony_ci{
37e5c31af7Sopenharmony_cinamespace
38e5c31af7Sopenharmony_ci{
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_ciclass SingleVertexArrayUsageGroup : public TestCaseGroup
42e5c31af7Sopenharmony_ci{
43e5c31af7Sopenharmony_cipublic:
44e5c31af7Sopenharmony_ci									SingleVertexArrayUsageGroup		(Context& context, Array::Usage usage);
45e5c31af7Sopenharmony_ci	virtual							~SingleVertexArrayUsageGroup	(void);
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_ci	virtual void					init							(void);
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_ciprivate:
50e5c31af7Sopenharmony_ci									SingleVertexArrayUsageGroup		(const SingleVertexArrayUsageGroup& other);
51e5c31af7Sopenharmony_ci	SingleVertexArrayUsageGroup&	operator=						(const SingleVertexArrayUsageGroup& other);
52e5c31af7Sopenharmony_ci
53e5c31af7Sopenharmony_ci	Array::Usage					m_usage;
54e5c31af7Sopenharmony_ci};
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_ciSingleVertexArrayUsageGroup::SingleVertexArrayUsageGroup (Context& context, Array::Usage usage)
57e5c31af7Sopenharmony_ci	: TestCaseGroup	(context, Array::usageTypeToString(usage).c_str(), Array::usageTypeToString(usage).c_str())
58e5c31af7Sopenharmony_ci	, m_usage		(usage)
59e5c31af7Sopenharmony_ci{
60e5c31af7Sopenharmony_ci}
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_ciSingleVertexArrayUsageGroup::~SingleVertexArrayUsageGroup (void)
63e5c31af7Sopenharmony_ci{
64e5c31af7Sopenharmony_ci}
65e5c31af7Sopenharmony_ci
66e5c31af7Sopenharmony_citemplate<class T>
67e5c31af7Sopenharmony_cistatic std::string typeToString (T t)
68e5c31af7Sopenharmony_ci{
69e5c31af7Sopenharmony_ci	std::stringstream strm;
70e5c31af7Sopenharmony_ci	strm << t;
71e5c31af7Sopenharmony_ci	return strm.str();
72e5c31af7Sopenharmony_ci}
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_civoid SingleVertexArrayUsageGroup::init (void)
75e5c31af7Sopenharmony_ci{
76e5c31af7Sopenharmony_ci	int					counts[]		= {1, 256};
77e5c31af7Sopenharmony_ci	int					strides[]		= {0, -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
78e5c31af7Sopenharmony_ci	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE};
79e5c31af7Sopenharmony_ci
80e5c31af7Sopenharmony_ci	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
81e5c31af7Sopenharmony_ci	{
82e5c31af7Sopenharmony_ci		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
83e5c31af7Sopenharmony_ci		{
84e5c31af7Sopenharmony_ci			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
85e5c31af7Sopenharmony_ci			{
86e5c31af7Sopenharmony_ci				const int			stride	= (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
87e5c31af7Sopenharmony_ci				const bool			aligned	= (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
88e5c31af7Sopenharmony_ci				const std::string	name	= "stride" + typeToString(stride) + "_" + Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_quads" + typeToString(counts[countNdx]);
89e5c31af7Sopenharmony_ci
90e5c31af7Sopenharmony_ci				MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
91e5c31af7Sopenharmony_ci																Array::OUTPUTTYPE_VEC2,
92e5c31af7Sopenharmony_ci																Array::STORAGE_BUFFER,
93e5c31af7Sopenharmony_ci																m_usage,
94e5c31af7Sopenharmony_ci																2,
95e5c31af7Sopenharmony_ci																0,
96e5c31af7Sopenharmony_ci																stride,
97e5c31af7Sopenharmony_ci																false,
98e5c31af7Sopenharmony_ci																GLValue::getMinValue(inputTypes[inputTypeNdx]),
99e5c31af7Sopenharmony_ci																GLValue::getMaxValue(inputTypes[inputTypeNdx]));
100e5c31af7Sopenharmony_ci
101e5c31af7Sopenharmony_ci				MultiVertexArrayTest::Spec spec;
102e5c31af7Sopenharmony_ci				spec.primitive	= Array::PRIMITIVE_TRIANGLES;
103e5c31af7Sopenharmony_ci				spec.drawCount	= counts[countNdx];
104e5c31af7Sopenharmony_ci				spec.first		= 0;
105e5c31af7Sopenharmony_ci				spec.arrays.push_back(arraySpec);
106e5c31af7Sopenharmony_ci
107e5c31af7Sopenharmony_ci				if (!aligned)
108e5c31af7Sopenharmony_ci					addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
109e5c31af7Sopenharmony_ci			}
110e5c31af7Sopenharmony_ci		}
111e5c31af7Sopenharmony_ci	}
112e5c31af7Sopenharmony_ci}
113e5c31af7Sopenharmony_ci
114e5c31af7Sopenharmony_ciclass SingleVertexArrayUsageTests : public TestCaseGroup
115e5c31af7Sopenharmony_ci{
116e5c31af7Sopenharmony_cipublic:
117e5c31af7Sopenharmony_ci									SingleVertexArrayUsageTests		(Context& context);
118e5c31af7Sopenharmony_ci	virtual							~SingleVertexArrayUsageTests	(void);
119e5c31af7Sopenharmony_ci
120e5c31af7Sopenharmony_ci	virtual void					init							(void);
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_ciprivate:
123e5c31af7Sopenharmony_ci									SingleVertexArrayUsageTests		(const SingleVertexArrayUsageTests& other);
124e5c31af7Sopenharmony_ci	SingleVertexArrayUsageTests&	operator=						(const SingleVertexArrayUsageTests& other);
125e5c31af7Sopenharmony_ci};
126e5c31af7Sopenharmony_ci
127e5c31af7Sopenharmony_ciSingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context)
128e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "usages", "Single vertex atribute, usage")
129e5c31af7Sopenharmony_ci{
130e5c31af7Sopenharmony_ci}
131e5c31af7Sopenharmony_ci
132e5c31af7Sopenharmony_ciSingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void)
133e5c31af7Sopenharmony_ci{
134e5c31af7Sopenharmony_ci}
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_civoid SingleVertexArrayUsageTests::init (void)
137e5c31af7Sopenharmony_ci{
138e5c31af7Sopenharmony_ci	// Test usage
139e5c31af7Sopenharmony_ci	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 };
140e5c31af7Sopenharmony_ci	for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
141e5c31af7Sopenharmony_ci	{
142e5c31af7Sopenharmony_ci		addChild(new SingleVertexArrayUsageGroup(m_context, usages[usageNdx]));
143e5c31af7Sopenharmony_ci	}
144e5c31af7Sopenharmony_ci}
145e5c31af7Sopenharmony_ci
146e5c31af7Sopenharmony_ciclass SingleVertexArrayStrideGroup : public TestCaseGroup
147e5c31af7Sopenharmony_ci{
148e5c31af7Sopenharmony_cipublic:
149e5c31af7Sopenharmony_ci									SingleVertexArrayStrideGroup	(Context& context, Array::InputType type);
150e5c31af7Sopenharmony_ci	virtual							~SingleVertexArrayStrideGroup	(void);
151e5c31af7Sopenharmony_ci
152e5c31af7Sopenharmony_ci	virtual void					init							(void);
153e5c31af7Sopenharmony_ci
154e5c31af7Sopenharmony_ciprivate:
155e5c31af7Sopenharmony_ci									SingleVertexArrayStrideGroup	(const SingleVertexArrayStrideGroup& other);
156e5c31af7Sopenharmony_ci	SingleVertexArrayStrideGroup&	operator=						(const SingleVertexArrayStrideGroup& other);
157e5c31af7Sopenharmony_ci
158e5c31af7Sopenharmony_ci	Array::InputType				m_type;
159e5c31af7Sopenharmony_ci};
160e5c31af7Sopenharmony_ci
161e5c31af7Sopenharmony_ciSingleVertexArrayStrideGroup::SingleVertexArrayStrideGroup (Context& context, Array::InputType type)
162e5c31af7Sopenharmony_ci	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
163e5c31af7Sopenharmony_ci	, m_type		(type)
164e5c31af7Sopenharmony_ci{
165e5c31af7Sopenharmony_ci}
166e5c31af7Sopenharmony_ci
167e5c31af7Sopenharmony_ciSingleVertexArrayStrideGroup::~SingleVertexArrayStrideGroup (void)
168e5c31af7Sopenharmony_ci{
169e5c31af7Sopenharmony_ci}
170e5c31af7Sopenharmony_ci
171e5c31af7Sopenharmony_civoid SingleVertexArrayStrideGroup::init (void)
172e5c31af7Sopenharmony_ci{
173e5c31af7Sopenharmony_ci	Array::Storage		storages[]		= {Array::STORAGE_USER, Array::STORAGE_BUFFER};
174e5c31af7Sopenharmony_ci	int					counts[]		= {1, 256};
175e5c31af7Sopenharmony_ci	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_ci	for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
178e5c31af7Sopenharmony_ci	{
179e5c31af7Sopenharmony_ci		for (int componentCount = 2; componentCount < 5; componentCount++)
180e5c31af7Sopenharmony_ci		{
181e5c31af7Sopenharmony_ci			for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
182e5c31af7Sopenharmony_ci			{
183e5c31af7Sopenharmony_ci				for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
184e5c31af7Sopenharmony_ci				{
185e5c31af7Sopenharmony_ci					const bool	packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
186e5c31af7Sopenharmony_ci					const int	stride			= (strides[strideNdx] < 0) ? ((packed) ? (16) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
187e5c31af7Sopenharmony_ci					const int	alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
188e5c31af7Sopenharmony_ci					const bool	bufferUnaligned	= (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % alignment) != 0;
189e5c31af7Sopenharmony_ci
190e5c31af7Sopenharmony_ci					std::string name = Array::storageToString(storages[storageNdx]) + "_stride" + typeToString(stride) + "_components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]);
191e5c31af7Sopenharmony_ci
192e5c31af7Sopenharmony_ci					if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4)
193e5c31af7Sopenharmony_ci						continue;
194e5c31af7Sopenharmony_ci
195e5c31af7Sopenharmony_ci					MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
196e5c31af7Sopenharmony_ci																	Array::OUTPUTTYPE_VEC4,
197e5c31af7Sopenharmony_ci																	storages[storageNdx],
198e5c31af7Sopenharmony_ci																	Array::USAGE_DYNAMIC_DRAW,
199e5c31af7Sopenharmony_ci																	componentCount,
200e5c31af7Sopenharmony_ci																	0,
201e5c31af7Sopenharmony_ci																	stride,
202e5c31af7Sopenharmony_ci																	false,
203e5c31af7Sopenharmony_ci																	GLValue::getMinValue(m_type),
204e5c31af7Sopenharmony_ci																	GLValue::getMaxValue(m_type));
205e5c31af7Sopenharmony_ci
206e5c31af7Sopenharmony_ci					MultiVertexArrayTest::Spec spec;
207e5c31af7Sopenharmony_ci					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
208e5c31af7Sopenharmony_ci					spec.drawCount	= counts[countNdx];
209e5c31af7Sopenharmony_ci					spec.first		= 0;
210e5c31af7Sopenharmony_ci					spec.arrays.push_back(arraySpec);
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_ci					if (bufferUnaligned)
213e5c31af7Sopenharmony_ci						addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
214e5c31af7Sopenharmony_ci				}
215e5c31af7Sopenharmony_ci			}
216e5c31af7Sopenharmony_ci		}
217e5c31af7Sopenharmony_ci	}
218e5c31af7Sopenharmony_ci}
219e5c31af7Sopenharmony_ci
220e5c31af7Sopenharmony_ciclass SingleVertexArrayStrideTests : public TestCaseGroup
221e5c31af7Sopenharmony_ci{
222e5c31af7Sopenharmony_cipublic:
223e5c31af7Sopenharmony_ci									SingleVertexArrayStrideTests	(Context& context);
224e5c31af7Sopenharmony_ci	virtual							~SingleVertexArrayStrideTests	(void);
225e5c31af7Sopenharmony_ci
226e5c31af7Sopenharmony_ci	virtual void					init							(void);
227e5c31af7Sopenharmony_ci
228e5c31af7Sopenharmony_ciprivate:
229e5c31af7Sopenharmony_ci									SingleVertexArrayStrideTests	(const SingleVertexArrayStrideTests& other);
230e5c31af7Sopenharmony_ci	SingleVertexArrayStrideTests&	operator=						(const SingleVertexArrayStrideTests& other);
231e5c31af7Sopenharmony_ci};
232e5c31af7Sopenharmony_ci
233e5c31af7Sopenharmony_ciSingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context)
234e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "strides", "Single stride vertex atribute")
235e5c31af7Sopenharmony_ci{
236e5c31af7Sopenharmony_ci}
237e5c31af7Sopenharmony_ci
238e5c31af7Sopenharmony_ciSingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void)
239e5c31af7Sopenharmony_ci{
240e5c31af7Sopenharmony_ci}
241e5c31af7Sopenharmony_ci
242e5c31af7Sopenharmony_civoid SingleVertexArrayStrideTests::init (void)
243e5c31af7Sopenharmony_ci{
244e5c31af7Sopenharmony_ci	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED, Array::INPUTTYPE_INT_2_10_10_10 };
245e5c31af7Sopenharmony_ci
246e5c31af7Sopenharmony_ci	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
247e5c31af7Sopenharmony_ci	{
248e5c31af7Sopenharmony_ci		addChild(new SingleVertexArrayStrideGroup(m_context, inputTypes[inputTypeNdx]));
249e5c31af7Sopenharmony_ci	}
250e5c31af7Sopenharmony_ci}
251e5c31af7Sopenharmony_ci
252e5c31af7Sopenharmony_ciclass SingleVertexArrayFirstGroup : public TestCaseGroup
253e5c31af7Sopenharmony_ci{
254e5c31af7Sopenharmony_cipublic:
255e5c31af7Sopenharmony_ci									SingleVertexArrayFirstGroup	(Context& context, Array::InputType type);
256e5c31af7Sopenharmony_ci	virtual							~SingleVertexArrayFirstGroup	(void);
257e5c31af7Sopenharmony_ci
258e5c31af7Sopenharmony_ci	virtual void					init							(void);
259e5c31af7Sopenharmony_ci
260e5c31af7Sopenharmony_ciprivate:
261e5c31af7Sopenharmony_ci									SingleVertexArrayFirstGroup	(const SingleVertexArrayFirstGroup& other);
262e5c31af7Sopenharmony_ci	SingleVertexArrayFirstGroup&	operator=						(const SingleVertexArrayFirstGroup& other);
263e5c31af7Sopenharmony_ci	Array::InputType				m_type;
264e5c31af7Sopenharmony_ci};
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ciSingleVertexArrayFirstGroup::SingleVertexArrayFirstGroup (Context& context, Array::InputType type)
267e5c31af7Sopenharmony_ci	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
268e5c31af7Sopenharmony_ci	, m_type		(type)
269e5c31af7Sopenharmony_ci{
270e5c31af7Sopenharmony_ci}
271e5c31af7Sopenharmony_ci
272e5c31af7Sopenharmony_ciSingleVertexArrayFirstGroup::~SingleVertexArrayFirstGroup (void)
273e5c31af7Sopenharmony_ci{
274e5c31af7Sopenharmony_ci}
275e5c31af7Sopenharmony_ci
276e5c31af7Sopenharmony_civoid SingleVertexArrayFirstGroup::init (void)
277e5c31af7Sopenharmony_ci{
278e5c31af7Sopenharmony_ci	int					counts[]		= {5, 256};
279e5c31af7Sopenharmony_ci	int					firsts[]		= {6, 24};
280e5c31af7Sopenharmony_ci	int					offsets[]		= {1, 17};
281e5c31af7Sopenharmony_ci	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
282e5c31af7Sopenharmony_ci
283e5c31af7Sopenharmony_ci	for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
284e5c31af7Sopenharmony_ci	{
285e5c31af7Sopenharmony_ci		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
286e5c31af7Sopenharmony_ci		{
287e5c31af7Sopenharmony_ci			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
288e5c31af7Sopenharmony_ci			{
289e5c31af7Sopenharmony_ci				for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++)
290e5c31af7Sopenharmony_ci				{
291e5c31af7Sopenharmony_ci					const bool	packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
292e5c31af7Sopenharmony_ci					const int	componentCount	= (packed) ? (4) : (2);
293e5c31af7Sopenharmony_ci					const int	stride			= (strides[strideNdx] < 0) ? ((packed) ? (8) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
294e5c31af7Sopenharmony_ci					const int	alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
295e5c31af7Sopenharmony_ci					const bool	aligned			= ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
296e5c31af7Sopenharmony_ci					std::string name			= "first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]);
297e5c31af7Sopenharmony_ci
298e5c31af7Sopenharmony_ci					MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
299e5c31af7Sopenharmony_ci																	Array::OUTPUTTYPE_VEC2,
300e5c31af7Sopenharmony_ci																	Array::STORAGE_BUFFER,
301e5c31af7Sopenharmony_ci																	Array::USAGE_DYNAMIC_DRAW,
302e5c31af7Sopenharmony_ci																	componentCount,
303e5c31af7Sopenharmony_ci																	offsets[offsetNdx],
304e5c31af7Sopenharmony_ci																	stride,
305e5c31af7Sopenharmony_ci																	false,
306e5c31af7Sopenharmony_ci																	GLValue::getMinValue(m_type),
307e5c31af7Sopenharmony_ci																	GLValue::getMaxValue(m_type));
308e5c31af7Sopenharmony_ci
309e5c31af7Sopenharmony_ci					MultiVertexArrayTest::Spec spec;
310e5c31af7Sopenharmony_ci					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
311e5c31af7Sopenharmony_ci					spec.drawCount	= counts[countNdx];
312e5c31af7Sopenharmony_ci					spec.first		= firsts[firstNdx];
313e5c31af7Sopenharmony_ci					spec.arrays.push_back(arraySpec);
314e5c31af7Sopenharmony_ci
315e5c31af7Sopenharmony_ci					if (!aligned)
316e5c31af7Sopenharmony_ci						addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
317e5c31af7Sopenharmony_ci				}
318e5c31af7Sopenharmony_ci			}
319e5c31af7Sopenharmony_ci		}
320e5c31af7Sopenharmony_ci	}
321e5c31af7Sopenharmony_ci}
322e5c31af7Sopenharmony_ci
323e5c31af7Sopenharmony_ciclass SingleVertexArrayFirstTests : public TestCaseGroup
324e5c31af7Sopenharmony_ci{
325e5c31af7Sopenharmony_cipublic:
326e5c31af7Sopenharmony_ci									SingleVertexArrayFirstTests	(Context& context);
327e5c31af7Sopenharmony_ci	virtual							~SingleVertexArrayFirstTests	(void);
328e5c31af7Sopenharmony_ci
329e5c31af7Sopenharmony_ci	virtual void					init							(void);
330e5c31af7Sopenharmony_ci
331e5c31af7Sopenharmony_ciprivate:
332e5c31af7Sopenharmony_ci									SingleVertexArrayFirstTests	(const SingleVertexArrayFirstTests& other);
333e5c31af7Sopenharmony_ci	SingleVertexArrayFirstTests&	operator=						(const SingleVertexArrayFirstTests& other);
334e5c31af7Sopenharmony_ci};
335e5c31af7Sopenharmony_ci
336e5c31af7Sopenharmony_ciSingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context)
337e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "first", "Single vertex attribute, different first values to drawArrays")
338e5c31af7Sopenharmony_ci{
339e5c31af7Sopenharmony_ci}
340e5c31af7Sopenharmony_ci
341e5c31af7Sopenharmony_ciSingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void)
342e5c31af7Sopenharmony_ci{
343e5c31af7Sopenharmony_ci}
344e5c31af7Sopenharmony_ci
345e5c31af7Sopenharmony_civoid SingleVertexArrayFirstTests::init (void)
346e5c31af7Sopenharmony_ci{
347e5c31af7Sopenharmony_ci	// Test offset with different input types, component counts and storage, Usage(?)
348e5c31af7Sopenharmony_ci	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_INT_2_10_10_10 };
349e5c31af7Sopenharmony_ci
350e5c31af7Sopenharmony_ci	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
351e5c31af7Sopenharmony_ci	{
352e5c31af7Sopenharmony_ci		addChild(new SingleVertexArrayFirstGroup(m_context, inputTypes[inputTypeNdx]));
353e5c31af7Sopenharmony_ci	}
354e5c31af7Sopenharmony_ci}
355e5c31af7Sopenharmony_ci
356e5c31af7Sopenharmony_ciclass SingleVertexArrayOffsetGroup : public TestCaseGroup
357e5c31af7Sopenharmony_ci{
358e5c31af7Sopenharmony_cipublic:
359e5c31af7Sopenharmony_ci									SingleVertexArrayOffsetGroup	(Context& context, Array::InputType type);
360e5c31af7Sopenharmony_ci	virtual							~SingleVertexArrayOffsetGroup	(void);
361e5c31af7Sopenharmony_ci
362e5c31af7Sopenharmony_ci	virtual void					init							(void);
363e5c31af7Sopenharmony_ci
364e5c31af7Sopenharmony_ciprivate:
365e5c31af7Sopenharmony_ci									SingleVertexArrayOffsetGroup	(const SingleVertexArrayOffsetGroup& other);
366e5c31af7Sopenharmony_ci	SingleVertexArrayOffsetGroup&	operator=						(const SingleVertexArrayOffsetGroup& other);
367e5c31af7Sopenharmony_ci	Array::InputType				m_type;
368e5c31af7Sopenharmony_ci};
369e5c31af7Sopenharmony_ci
370e5c31af7Sopenharmony_ciSingleVertexArrayOffsetGroup::SingleVertexArrayOffsetGroup (Context& context, Array::InputType type)
371e5c31af7Sopenharmony_ci	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
372e5c31af7Sopenharmony_ci	, m_type		(type)
373e5c31af7Sopenharmony_ci{
374e5c31af7Sopenharmony_ci}
375e5c31af7Sopenharmony_ci
376e5c31af7Sopenharmony_ciSingleVertexArrayOffsetGroup::~SingleVertexArrayOffsetGroup (void)
377e5c31af7Sopenharmony_ci{
378e5c31af7Sopenharmony_ci}
379e5c31af7Sopenharmony_ci
380e5c31af7Sopenharmony_civoid SingleVertexArrayOffsetGroup::init (void)
381e5c31af7Sopenharmony_ci{
382e5c31af7Sopenharmony_ci	int					counts[]		= {1, 256};
383e5c31af7Sopenharmony_ci	int					offsets[]		= {1, 4, 17, 32};
384e5c31af7Sopenharmony_ci	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
385e5c31af7Sopenharmony_ci
386e5c31af7Sopenharmony_ci	for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
387e5c31af7Sopenharmony_ci	{
388e5c31af7Sopenharmony_ci		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
389e5c31af7Sopenharmony_ci		{
390e5c31af7Sopenharmony_ci			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
391e5c31af7Sopenharmony_ci			{
392e5c31af7Sopenharmony_ci				const bool			packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
393e5c31af7Sopenharmony_ci				const int			componentCount	= (packed) ? (4) : (2);
394e5c31af7Sopenharmony_ci				const int			stride			= (strides[strideNdx] < 0 ? Array::inputTypeSize(m_type) * componentCount : strides[strideNdx]);
395e5c31af7Sopenharmony_ci				const int			alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
396e5c31af7Sopenharmony_ci				const bool			aligned			= ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
397e5c31af7Sopenharmony_ci				const std::string	name			= "offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(strides[strideNdx]) + "_quads" + typeToString(counts[countNdx]);
398e5c31af7Sopenharmony_ci
399e5c31af7Sopenharmony_ci				MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
400e5c31af7Sopenharmony_ci																Array::OUTPUTTYPE_VEC2,
401e5c31af7Sopenharmony_ci																Array::STORAGE_BUFFER,
402e5c31af7Sopenharmony_ci																Array::USAGE_DYNAMIC_DRAW,
403e5c31af7Sopenharmony_ci																componentCount,
404e5c31af7Sopenharmony_ci																offsets[offsetNdx],
405e5c31af7Sopenharmony_ci																stride,
406e5c31af7Sopenharmony_ci																false,
407e5c31af7Sopenharmony_ci																GLValue::getMinValue(m_type),
408e5c31af7Sopenharmony_ci																GLValue::getMaxValue(m_type));
409e5c31af7Sopenharmony_ci
410e5c31af7Sopenharmony_ci				MultiVertexArrayTest::Spec spec;
411e5c31af7Sopenharmony_ci				spec.primitive	= Array::PRIMITIVE_TRIANGLES;
412e5c31af7Sopenharmony_ci				spec.drawCount	= counts[countNdx];
413e5c31af7Sopenharmony_ci				spec.first		= 0;
414e5c31af7Sopenharmony_ci				spec.arrays.push_back(arraySpec);
415e5c31af7Sopenharmony_ci
416e5c31af7Sopenharmony_ci				if (!aligned)
417e5c31af7Sopenharmony_ci					addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
418e5c31af7Sopenharmony_ci			}
419e5c31af7Sopenharmony_ci		}
420e5c31af7Sopenharmony_ci	}
421e5c31af7Sopenharmony_ci}
422e5c31af7Sopenharmony_ci
423e5c31af7Sopenharmony_ciclass SingleVertexArrayOffsetTests : public TestCaseGroup
424e5c31af7Sopenharmony_ci{
425e5c31af7Sopenharmony_cipublic:
426e5c31af7Sopenharmony_ci									SingleVertexArrayOffsetTests	(Context& context);
427e5c31af7Sopenharmony_ci	virtual							~SingleVertexArrayOffsetTests	(void);
428e5c31af7Sopenharmony_ci
429e5c31af7Sopenharmony_ci	virtual void					init							(void);
430e5c31af7Sopenharmony_ci
431e5c31af7Sopenharmony_ciprivate:
432e5c31af7Sopenharmony_ci									SingleVertexArrayOffsetTests	(const SingleVertexArrayOffsetTests& other);
433e5c31af7Sopenharmony_ci	SingleVertexArrayOffsetTests&	operator=						(const SingleVertexArrayOffsetTests& other);
434e5c31af7Sopenharmony_ci};
435e5c31af7Sopenharmony_ci
436e5c31af7Sopenharmony_ciSingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context)
437e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "offset", "Single vertex atribute offset element")
438e5c31af7Sopenharmony_ci{
439e5c31af7Sopenharmony_ci}
440e5c31af7Sopenharmony_ci
441e5c31af7Sopenharmony_ciSingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void)
442e5c31af7Sopenharmony_ci{
443e5c31af7Sopenharmony_ci}
444e5c31af7Sopenharmony_ci
445e5c31af7Sopenharmony_civoid SingleVertexArrayOffsetTests::init (void)
446e5c31af7Sopenharmony_ci{
447e5c31af7Sopenharmony_ci	// Test offset with different input types, component counts and storage, Usage(?)
448e5c31af7Sopenharmony_ci	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_INT_2_10_10_10 };
449e5c31af7Sopenharmony_ci
450e5c31af7Sopenharmony_ci	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
451e5c31af7Sopenharmony_ci	{
452e5c31af7Sopenharmony_ci		addChild(new SingleVertexArrayOffsetGroup(m_context, inputTypes[inputTypeNdx]));
453e5c31af7Sopenharmony_ci	}
454e5c31af7Sopenharmony_ci}
455e5c31af7Sopenharmony_ci
456e5c31af7Sopenharmony_ci} // anonymous
457e5c31af7Sopenharmony_ci
458e5c31af7Sopenharmony_ciVertexArrayTests::VertexArrayTests (Context& context)
459e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests")
460e5c31af7Sopenharmony_ci{
461e5c31af7Sopenharmony_ci}
462e5c31af7Sopenharmony_ci
463e5c31af7Sopenharmony_ciVertexArrayTests::~VertexArrayTests (void)
464e5c31af7Sopenharmony_ci{
465e5c31af7Sopenharmony_ci}
466e5c31af7Sopenharmony_ci
467e5c31af7Sopenharmony_civoid VertexArrayTests::init (void)
468e5c31af7Sopenharmony_ci{
469e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "single_attribute", "Single attribute");
470e5c31af7Sopenharmony_ci	addChild(group);
471e5c31af7Sopenharmony_ci
472e5c31af7Sopenharmony_ci	// .single_attribute
473e5c31af7Sopenharmony_ci	{
474e5c31af7Sopenharmony_ci		group->addChild(new SingleVertexArrayStrideTests(m_context));
475e5c31af7Sopenharmony_ci		group->addChild(new SingleVertexArrayUsageTests(m_context));
476e5c31af7Sopenharmony_ci		group->addChild(new SingleVertexArrayOffsetTests(m_context));
477e5c31af7Sopenharmony_ci		group->addChild(new SingleVertexArrayFirstTests(m_context));
478e5c31af7Sopenharmony_ci	}
479e5c31af7Sopenharmony_ci}
480e5c31af7Sopenharmony_ci
481e5c31af7Sopenharmony_ci} // Stress
482e5c31af7Sopenharmony_ci} // gles3
483e5c31af7Sopenharmony_ci} // deqp
484