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 Drawing tests.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "es3fDrawTests.hpp"
25e5c31af7Sopenharmony_ci#include "glsDrawTest.hpp"
26e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp"
27e5c31af7Sopenharmony_ci#include "sglrGLContext.hpp"
28e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
29e5c31af7Sopenharmony_ci#include "deRandom.hpp"
30e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
31e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp"
32e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp"
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_ci#include <set>
35e5c31af7Sopenharmony_ci
36e5c31af7Sopenharmony_cinamespace deqp
37e5c31af7Sopenharmony_ci{
38e5c31af7Sopenharmony_cinamespace gles3
39e5c31af7Sopenharmony_ci{
40e5c31af7Sopenharmony_cinamespace Functional
41e5c31af7Sopenharmony_ci{
42e5c31af7Sopenharmony_cinamespace
43e5c31af7Sopenharmony_ci{
44e5c31af7Sopenharmony_ci
45e5c31af7Sopenharmony_cienum TestIterationType
46e5c31af7Sopenharmony_ci{
47e5c31af7Sopenharmony_ci	TYPE_DRAW_COUNT,		// !< test with 1, 5, and 25 primitives
48e5c31af7Sopenharmony_ci	TYPE_INSTANCE_COUNT,	// !< test with 1, 4, and 11 instances
49e5c31af7Sopenharmony_ci	TYPE_INDEX_RANGE,		// !< test with index range of [0, 23], [23, 40], and [5, 5]
50e5c31af7Sopenharmony_ci
51e5c31af7Sopenharmony_ci	TYPE_LAST
52e5c31af7Sopenharmony_ci};
53e5c31af7Sopenharmony_ci
54e5c31af7Sopenharmony_cistatic void addTestIterations (gls::DrawTest* test, const gls::DrawTestSpec& baseSpec, TestIterationType type)
55e5c31af7Sopenharmony_ci{
56e5c31af7Sopenharmony_ci	gls::DrawTestSpec spec(baseSpec);
57e5c31af7Sopenharmony_ci
58e5c31af7Sopenharmony_ci	if (type == TYPE_DRAW_COUNT)
59e5c31af7Sopenharmony_ci	{
60e5c31af7Sopenharmony_ci		spec.primitiveCount = 1;
61e5c31af7Sopenharmony_ci		test->addIteration(spec, "draw count = 1");
62e5c31af7Sopenharmony_ci
63e5c31af7Sopenharmony_ci		spec.primitiveCount = 5;
64e5c31af7Sopenharmony_ci		test->addIteration(spec, "draw count = 5");
65e5c31af7Sopenharmony_ci
66e5c31af7Sopenharmony_ci		spec.primitiveCount = 25;
67e5c31af7Sopenharmony_ci		test->addIteration(spec, "draw count = 25");
68e5c31af7Sopenharmony_ci	}
69e5c31af7Sopenharmony_ci	else if (type == TYPE_INSTANCE_COUNT)
70e5c31af7Sopenharmony_ci	{
71e5c31af7Sopenharmony_ci		spec.instanceCount = 1;
72e5c31af7Sopenharmony_ci		test->addIteration(spec, "instance count = 1");
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ci		spec.instanceCount = 4;
75e5c31af7Sopenharmony_ci		test->addIteration(spec, "instance count = 4");
76e5c31af7Sopenharmony_ci
77e5c31af7Sopenharmony_ci		spec.instanceCount = 11;
78e5c31af7Sopenharmony_ci		test->addIteration(spec, "instance count = 11");
79e5c31af7Sopenharmony_ci	}
80e5c31af7Sopenharmony_ci	else if (type == TYPE_INDEX_RANGE)
81e5c31af7Sopenharmony_ci	{
82e5c31af7Sopenharmony_ci		spec.indexMin = 0;
83e5c31af7Sopenharmony_ci		spec.indexMax = 23;
84e5c31af7Sopenharmony_ci		test->addIteration(spec, "index range = [0, 23]");
85e5c31af7Sopenharmony_ci
86e5c31af7Sopenharmony_ci		spec.indexMin = 23;
87e5c31af7Sopenharmony_ci		spec.indexMax = 40;
88e5c31af7Sopenharmony_ci		test->addIteration(spec, "index range = [23, 40]");
89e5c31af7Sopenharmony_ci
90e5c31af7Sopenharmony_ci		// Only makes sense with points
91e5c31af7Sopenharmony_ci		if (spec.primitive == gls::DrawTestSpec::PRIMITIVE_POINTS)
92e5c31af7Sopenharmony_ci		{
93e5c31af7Sopenharmony_ci			spec.indexMin = 5;
94e5c31af7Sopenharmony_ci			spec.indexMax = 5;
95e5c31af7Sopenharmony_ci			test->addIteration(spec, "index range = [5, 5]");
96e5c31af7Sopenharmony_ci		}
97e5c31af7Sopenharmony_ci	}
98e5c31af7Sopenharmony_ci	else
99e5c31af7Sopenharmony_ci		DE_ASSERT(false);
100e5c31af7Sopenharmony_ci}
101e5c31af7Sopenharmony_ci
102e5c31af7Sopenharmony_cistatic void genBasicSpec (gls::DrawTestSpec& spec, gls::DrawTestSpec::DrawMethod method)
103e5c31af7Sopenharmony_ci{
104e5c31af7Sopenharmony_ci	spec.apiType				= glu::ApiType::es(3,0);
105e5c31af7Sopenharmony_ci	spec.primitive				= gls::DrawTestSpec::PRIMITIVE_TRIANGLES;
106e5c31af7Sopenharmony_ci	spec.primitiveCount			= 5;
107e5c31af7Sopenharmony_ci	spec.drawMethod				= method;
108e5c31af7Sopenharmony_ci	spec.indexType				= gls::DrawTestSpec::INDEXTYPE_LAST;
109e5c31af7Sopenharmony_ci	spec.indexPointerOffset		= 0;
110e5c31af7Sopenharmony_ci	spec.indexStorage			= gls::DrawTestSpec::STORAGE_LAST;
111e5c31af7Sopenharmony_ci	spec.first					= 0;
112e5c31af7Sopenharmony_ci	spec.indexMin				= 0;
113e5c31af7Sopenharmony_ci	spec.indexMax				= 0;
114e5c31af7Sopenharmony_ci	spec.instanceCount			= 1;
115e5c31af7Sopenharmony_ci
116e5c31af7Sopenharmony_ci	spec.attribs.resize(2);
117e5c31af7Sopenharmony_ci
118e5c31af7Sopenharmony_ci	spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
119e5c31af7Sopenharmony_ci	spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
120e5c31af7Sopenharmony_ci	spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
121e5c31af7Sopenharmony_ci	spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
122e5c31af7Sopenharmony_ci	spec.attribs[0].componentCount			= 4;
123e5c31af7Sopenharmony_ci	spec.attribs[0].offset					= 0;
124e5c31af7Sopenharmony_ci	spec.attribs[0].stride					= 0;
125e5c31af7Sopenharmony_ci	spec.attribs[0].normalize				= false;
126e5c31af7Sopenharmony_ci	spec.attribs[0].instanceDivisor			= 0;
127e5c31af7Sopenharmony_ci	spec.attribs[0].useDefaultAttribute		= false;
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_ci	spec.attribs[1].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
130e5c31af7Sopenharmony_ci	spec.attribs[1].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
131e5c31af7Sopenharmony_ci	spec.attribs[1].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
132e5c31af7Sopenharmony_ci	spec.attribs[1].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
133e5c31af7Sopenharmony_ci	spec.attribs[1].componentCount			= 2;
134e5c31af7Sopenharmony_ci	spec.attribs[1].offset					= 0;
135e5c31af7Sopenharmony_ci	spec.attribs[1].stride					= 0;
136e5c31af7Sopenharmony_ci	spec.attribs[1].normalize				= false;
137e5c31af7Sopenharmony_ci	spec.attribs[1].instanceDivisor			= 0;
138e5c31af7Sopenharmony_ci	spec.attribs[1].useDefaultAttribute		= false;
139e5c31af7Sopenharmony_ci}
140e5c31af7Sopenharmony_ci
141e5c31af7Sopenharmony_ciclass AttributeGroup : public TestCaseGroup
142e5c31af7Sopenharmony_ci{
143e5c31af7Sopenharmony_cipublic:
144e5c31af7Sopenharmony_ci									AttributeGroup	(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage);
145e5c31af7Sopenharmony_ci									~AttributeGroup	(void);
146e5c31af7Sopenharmony_ci
147e5c31af7Sopenharmony_ci	void							init			(void);
148e5c31af7Sopenharmony_ci
149e5c31af7Sopenharmony_ciprivate:
150e5c31af7Sopenharmony_ci	gls::DrawTestSpec::DrawMethod	m_method;
151e5c31af7Sopenharmony_ci	gls::DrawTestSpec::Primitive	m_primitive;
152e5c31af7Sopenharmony_ci	gls::DrawTestSpec::IndexType	m_indexType;
153e5c31af7Sopenharmony_ci	gls::DrawTestSpec::Storage		m_indexStorage;
154e5c31af7Sopenharmony_ci};
155e5c31af7Sopenharmony_ci
156e5c31af7Sopenharmony_ciAttributeGroup::AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage)
157e5c31af7Sopenharmony_ci	: TestCaseGroup		(context, name, descr)
158e5c31af7Sopenharmony_ci	, m_method			(drawMethod)
159e5c31af7Sopenharmony_ci	, m_primitive		(primitive)
160e5c31af7Sopenharmony_ci	, m_indexType		(indexType)
161e5c31af7Sopenharmony_ci	, m_indexStorage	(indexStorage)
162e5c31af7Sopenharmony_ci{
163e5c31af7Sopenharmony_ci}
164e5c31af7Sopenharmony_ci
165e5c31af7Sopenharmony_ciAttributeGroup::~AttributeGroup (void)
166e5c31af7Sopenharmony_ci{
167e5c31af7Sopenharmony_ci}
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_civoid AttributeGroup::init (void)
170e5c31af7Sopenharmony_ci{
171e5c31af7Sopenharmony_ci	// select test type
172e5c31af7Sopenharmony_ci	const bool				instanced			= (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED) ||
173e5c31af7Sopenharmony_ci												  (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED);
174e5c31af7Sopenharmony_ci	const bool				ranged				= (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED);
175e5c31af7Sopenharmony_ci	const TestIterationType	testType			= (instanced) ? (TYPE_INSTANCE_COUNT) : ((ranged) ? (TYPE_INDEX_RANGE) : (TYPE_DRAW_COUNT));
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_ci	// Single attribute
178e5c31af7Sopenharmony_ci	{
179e5c31af7Sopenharmony_ci		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
180e5c31af7Sopenharmony_ci		gls::DrawTestSpec	spec;
181e5c31af7Sopenharmony_ci
182e5c31af7Sopenharmony_ci		spec.apiType							= glu::ApiType::es(3,0);
183e5c31af7Sopenharmony_ci		spec.primitive							= m_primitive;
184e5c31af7Sopenharmony_ci		spec.primitiveCount						= 5;
185e5c31af7Sopenharmony_ci		spec.drawMethod							= m_method;
186e5c31af7Sopenharmony_ci		spec.indexType							= m_indexType;
187e5c31af7Sopenharmony_ci		spec.indexPointerOffset					= 0;
188e5c31af7Sopenharmony_ci		spec.indexStorage						= m_indexStorage;
189e5c31af7Sopenharmony_ci		spec.first								= 0;
190e5c31af7Sopenharmony_ci		spec.indexMin							= 0;
191e5c31af7Sopenharmony_ci		spec.indexMax							= 0;
192e5c31af7Sopenharmony_ci		spec.instanceCount						= 1;
193e5c31af7Sopenharmony_ci
194e5c31af7Sopenharmony_ci		spec.attribs.resize(1);
195e5c31af7Sopenharmony_ci
196e5c31af7Sopenharmony_ci		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
197e5c31af7Sopenharmony_ci		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
198e5c31af7Sopenharmony_ci		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
199e5c31af7Sopenharmony_ci		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
200e5c31af7Sopenharmony_ci		spec.attribs[0].componentCount			= 2;
201e5c31af7Sopenharmony_ci		spec.attribs[0].offset					= 0;
202e5c31af7Sopenharmony_ci		spec.attribs[0].stride					= 0;
203e5c31af7Sopenharmony_ci		spec.attribs[0].normalize				= false;
204e5c31af7Sopenharmony_ci		spec.attribs[0].instanceDivisor			= 0;
205e5c31af7Sopenharmony_ci		spec.attribs[0].useDefaultAttribute		= false;
206e5c31af7Sopenharmony_ci
207e5c31af7Sopenharmony_ci		addTestIterations(test, spec, testType);
208e5c31af7Sopenharmony_ci
209e5c31af7Sopenharmony_ci		this->addChild(test);
210e5c31af7Sopenharmony_ci	}
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_ci	// Multiple attribute
213e5c31af7Sopenharmony_ci	{
214e5c31af7Sopenharmony_ci		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays.");
215e5c31af7Sopenharmony_ci		gls::DrawTestSpec	spec;
216e5c31af7Sopenharmony_ci
217e5c31af7Sopenharmony_ci		spec.apiType							= glu::ApiType::es(3,0);
218e5c31af7Sopenharmony_ci		spec.primitive							= m_primitive;
219e5c31af7Sopenharmony_ci		spec.primitiveCount						= 5;
220e5c31af7Sopenharmony_ci		spec.drawMethod							= m_method;
221e5c31af7Sopenharmony_ci		spec.indexType							= m_indexType;
222e5c31af7Sopenharmony_ci		spec.indexPointerOffset					= 0;
223e5c31af7Sopenharmony_ci		spec.indexStorage						= m_indexStorage;
224e5c31af7Sopenharmony_ci		spec.first								= 0;
225e5c31af7Sopenharmony_ci		spec.indexMin							= 0;
226e5c31af7Sopenharmony_ci		spec.indexMax							= 0;
227e5c31af7Sopenharmony_ci		spec.instanceCount						= 1;
228e5c31af7Sopenharmony_ci
229e5c31af7Sopenharmony_ci		spec.attribs.resize(2);
230e5c31af7Sopenharmony_ci
231e5c31af7Sopenharmony_ci		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
232e5c31af7Sopenharmony_ci		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
233e5c31af7Sopenharmony_ci		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
234e5c31af7Sopenharmony_ci		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
235e5c31af7Sopenharmony_ci		spec.attribs[0].componentCount			= 4;
236e5c31af7Sopenharmony_ci		spec.attribs[0].offset					= 0;
237e5c31af7Sopenharmony_ci		spec.attribs[0].stride					= 0;
238e5c31af7Sopenharmony_ci		spec.attribs[0].normalize				= false;
239e5c31af7Sopenharmony_ci		spec.attribs[0].instanceDivisor			= 0;
240e5c31af7Sopenharmony_ci		spec.attribs[0].useDefaultAttribute		= false;
241e5c31af7Sopenharmony_ci
242e5c31af7Sopenharmony_ci		spec.attribs[1].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
243e5c31af7Sopenharmony_ci		spec.attribs[1].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
244e5c31af7Sopenharmony_ci		spec.attribs[1].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
245e5c31af7Sopenharmony_ci		spec.attribs[1].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
246e5c31af7Sopenharmony_ci		spec.attribs[1].componentCount			= 2;
247e5c31af7Sopenharmony_ci		spec.attribs[1].offset					= 0;
248e5c31af7Sopenharmony_ci		spec.attribs[1].stride					= 0;
249e5c31af7Sopenharmony_ci		spec.attribs[1].normalize				= false;
250e5c31af7Sopenharmony_ci		spec.attribs[1].instanceDivisor			= 0;
251e5c31af7Sopenharmony_ci		spec.attribs[1].useDefaultAttribute		= false;
252e5c31af7Sopenharmony_ci
253e5c31af7Sopenharmony_ci		addTestIterations(test, spec, testType);
254e5c31af7Sopenharmony_ci
255e5c31af7Sopenharmony_ci		this->addChild(test);
256e5c31af7Sopenharmony_ci	}
257e5c31af7Sopenharmony_ci
258e5c31af7Sopenharmony_ci	// Multiple attribute, second one divided
259e5c31af7Sopenharmony_ci	{
260e5c31af7Sopenharmony_ci		gls::DrawTest*		test					= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "instanced_attributes", "Instanced attribute array.");
261e5c31af7Sopenharmony_ci		gls::DrawTestSpec	spec;
262e5c31af7Sopenharmony_ci
263e5c31af7Sopenharmony_ci		spec.apiType								= glu::ApiType::es(3,0);
264e5c31af7Sopenharmony_ci		spec.primitive								= m_primitive;
265e5c31af7Sopenharmony_ci		spec.primitiveCount							= 5;
266e5c31af7Sopenharmony_ci		spec.drawMethod								= m_method;
267e5c31af7Sopenharmony_ci		spec.indexType								= m_indexType;
268e5c31af7Sopenharmony_ci		spec.indexPointerOffset						= 0;
269e5c31af7Sopenharmony_ci		spec.indexStorage							= m_indexStorage;
270e5c31af7Sopenharmony_ci		spec.first									= 0;
271e5c31af7Sopenharmony_ci		spec.indexMin								= 0;
272e5c31af7Sopenharmony_ci		spec.indexMax								= 0;
273e5c31af7Sopenharmony_ci		spec.instanceCount							= 1;
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ci		spec.attribs.resize(3);
276e5c31af7Sopenharmony_ci
277e5c31af7Sopenharmony_ci		spec.attribs[0].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
278e5c31af7Sopenharmony_ci		spec.attribs[0].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
279e5c31af7Sopenharmony_ci		spec.attribs[0].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
280e5c31af7Sopenharmony_ci		spec.attribs[0].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
281e5c31af7Sopenharmony_ci		spec.attribs[0].componentCount				= 4;
282e5c31af7Sopenharmony_ci		spec.attribs[0].offset						= 0;
283e5c31af7Sopenharmony_ci		spec.attribs[0].stride						= 0;
284e5c31af7Sopenharmony_ci		spec.attribs[0].normalize					= false;
285e5c31af7Sopenharmony_ci		spec.attribs[0].instanceDivisor				= 0;
286e5c31af7Sopenharmony_ci		spec.attribs[0].useDefaultAttribute			= false;
287e5c31af7Sopenharmony_ci
288e5c31af7Sopenharmony_ci		// Add another position component so the instances wont be drawn on each other
289e5c31af7Sopenharmony_ci		spec.attribs[1].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
290e5c31af7Sopenharmony_ci		spec.attribs[1].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
291e5c31af7Sopenharmony_ci		spec.attribs[1].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
292e5c31af7Sopenharmony_ci		spec.attribs[1].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
293e5c31af7Sopenharmony_ci		spec.attribs[1].componentCount				= 2;
294e5c31af7Sopenharmony_ci		spec.attribs[1].offset						= 0;
295e5c31af7Sopenharmony_ci		spec.attribs[1].stride						= 0;
296e5c31af7Sopenharmony_ci		spec.attribs[1].normalize					= false;
297e5c31af7Sopenharmony_ci		spec.attribs[1].instanceDivisor				= 1;
298e5c31af7Sopenharmony_ci		spec.attribs[1].useDefaultAttribute			= false;
299e5c31af7Sopenharmony_ci		spec.attribs[1].additionalPositionAttribute	= true;
300e5c31af7Sopenharmony_ci
301e5c31af7Sopenharmony_ci		// Instanced color
302e5c31af7Sopenharmony_ci		spec.attribs[2].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
303e5c31af7Sopenharmony_ci		spec.attribs[2].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
304e5c31af7Sopenharmony_ci		spec.attribs[2].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
305e5c31af7Sopenharmony_ci		spec.attribs[2].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
306e5c31af7Sopenharmony_ci		spec.attribs[2].componentCount				= 3;
307e5c31af7Sopenharmony_ci		spec.attribs[2].offset						= 0;
308e5c31af7Sopenharmony_ci		spec.attribs[2].stride						= 0;
309e5c31af7Sopenharmony_ci		spec.attribs[2].normalize					= false;
310e5c31af7Sopenharmony_ci		spec.attribs[2].instanceDivisor				= 1;
311e5c31af7Sopenharmony_ci		spec.attribs[2].useDefaultAttribute			= false;
312e5c31af7Sopenharmony_ci
313e5c31af7Sopenharmony_ci		addTestIterations(test, spec, testType);
314e5c31af7Sopenharmony_ci
315e5c31af7Sopenharmony_ci		this->addChild(test);
316e5c31af7Sopenharmony_ci	}
317e5c31af7Sopenharmony_ci
318e5c31af7Sopenharmony_ci	// Multiple attribute, second one default
319e5c31af7Sopenharmony_ci	{
320e5c31af7Sopenharmony_ci		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*.");
321e5c31af7Sopenharmony_ci		gls::DrawTestSpec	spec;
322e5c31af7Sopenharmony_ci
323e5c31af7Sopenharmony_ci		spec.apiType							= glu::ApiType::es(3,0);
324e5c31af7Sopenharmony_ci		spec.primitive							= m_primitive;
325e5c31af7Sopenharmony_ci		spec.primitiveCount						= 5;
326e5c31af7Sopenharmony_ci		spec.drawMethod							= m_method;
327e5c31af7Sopenharmony_ci		spec.indexType							= m_indexType;
328e5c31af7Sopenharmony_ci		spec.indexPointerOffset					= 0;
329e5c31af7Sopenharmony_ci		spec.indexStorage						= m_indexStorage;
330e5c31af7Sopenharmony_ci		spec.first								= 0;
331e5c31af7Sopenharmony_ci		spec.indexMin							= 0;
332e5c31af7Sopenharmony_ci		spec.indexMax							= 20; // \note addTestIterations is not called for the spec, so we must ensure [indexMin, indexMax] is a good range
333e5c31af7Sopenharmony_ci		spec.instanceCount						= 1;
334e5c31af7Sopenharmony_ci
335e5c31af7Sopenharmony_ci		spec.attribs.resize(2);
336e5c31af7Sopenharmony_ci
337e5c31af7Sopenharmony_ci		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
338e5c31af7Sopenharmony_ci		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
339e5c31af7Sopenharmony_ci		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
340e5c31af7Sopenharmony_ci		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
341e5c31af7Sopenharmony_ci		spec.attribs[0].componentCount			= 2;
342e5c31af7Sopenharmony_ci		spec.attribs[0].offset					= 0;
343e5c31af7Sopenharmony_ci		spec.attribs[0].stride					= 0;
344e5c31af7Sopenharmony_ci		spec.attribs[0].normalize				= false;
345e5c31af7Sopenharmony_ci		spec.attribs[0].instanceDivisor			= 0;
346e5c31af7Sopenharmony_ci		spec.attribs[0].useDefaultAttribute		= false;
347e5c31af7Sopenharmony_ci
348e5c31af7Sopenharmony_ci		struct IOPair
349e5c31af7Sopenharmony_ci		{
350e5c31af7Sopenharmony_ci			gls::DrawTestSpec::InputType  input;
351e5c31af7Sopenharmony_ci			gls::DrawTestSpec::OutputType output;
352e5c31af7Sopenharmony_ci			int							  componentCount;
353e5c31af7Sopenharmony_ci		} iopairs[] =
354e5c31af7Sopenharmony_ci		{
355e5c31af7Sopenharmony_ci			{ gls::DrawTestSpec::INPUTTYPE_FLOAT,        gls::DrawTestSpec::OUTPUTTYPE_VEC2,  4 },
356e5c31af7Sopenharmony_ci			{ gls::DrawTestSpec::INPUTTYPE_FLOAT,        gls::DrawTestSpec::OUTPUTTYPE_VEC4,  2 },
357e5c31af7Sopenharmony_ci			{ gls::DrawTestSpec::INPUTTYPE_INT,          gls::DrawTestSpec::OUTPUTTYPE_IVEC3, 4 },
358e5c31af7Sopenharmony_ci			{ gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT, gls::DrawTestSpec::OUTPUTTYPE_UVEC2, 4 },
359e5c31af7Sopenharmony_ci		};
360e5c31af7Sopenharmony_ci
361e5c31af7Sopenharmony_ci		for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
362e5c31af7Sopenharmony_ci		{
363e5c31af7Sopenharmony_ci			const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);
364e5c31af7Sopenharmony_ci
365e5c31af7Sopenharmony_ci			spec.attribs[1].inputType			= iopairs[ioNdx].input;
366e5c31af7Sopenharmony_ci			spec.attribs[1].outputType			= iopairs[ioNdx].output;
367e5c31af7Sopenharmony_ci			spec.attribs[1].storage				= gls::DrawTestSpec::STORAGE_BUFFER;
368e5c31af7Sopenharmony_ci			spec.attribs[1].usage				= gls::DrawTestSpec::USAGE_STATIC_DRAW;
369e5c31af7Sopenharmony_ci			spec.attribs[1].componentCount		= iopairs[ioNdx].componentCount;
370e5c31af7Sopenharmony_ci			spec.attribs[1].offset				= 0;
371e5c31af7Sopenharmony_ci			spec.attribs[1].stride				= 0;
372e5c31af7Sopenharmony_ci			spec.attribs[1].normalize			= false;
373e5c31af7Sopenharmony_ci			spec.attribs[1].instanceDivisor		= 0;
374e5c31af7Sopenharmony_ci			spec.attribs[1].useDefaultAttribute	= true;
375e5c31af7Sopenharmony_ci
376e5c31af7Sopenharmony_ci			test->addIteration(spec, desc.c_str());
377e5c31af7Sopenharmony_ci		}
378e5c31af7Sopenharmony_ci
379e5c31af7Sopenharmony_ci		this->addChild(test);
380e5c31af7Sopenharmony_ci	}
381e5c31af7Sopenharmony_ci}
382e5c31af7Sopenharmony_ci
383e5c31af7Sopenharmony_ciclass IndexGroup : public TestCaseGroup
384e5c31af7Sopenharmony_ci{
385e5c31af7Sopenharmony_cipublic:
386e5c31af7Sopenharmony_ci									IndexGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
387e5c31af7Sopenharmony_ci									~IndexGroup		(void);
388e5c31af7Sopenharmony_ci
389e5c31af7Sopenharmony_ci	void							init			(void);
390e5c31af7Sopenharmony_ci
391e5c31af7Sopenharmony_ciprivate:
392e5c31af7Sopenharmony_ci	gls::DrawTestSpec::DrawMethod	m_method;
393e5c31af7Sopenharmony_ci};
394e5c31af7Sopenharmony_ci
395e5c31af7Sopenharmony_ciIndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
396e5c31af7Sopenharmony_ci	: TestCaseGroup		(context, name, descr)
397e5c31af7Sopenharmony_ci	, m_method			(drawMethod)
398e5c31af7Sopenharmony_ci{
399e5c31af7Sopenharmony_ci}
400e5c31af7Sopenharmony_ci
401e5c31af7Sopenharmony_ciIndexGroup::~IndexGroup (void)
402e5c31af7Sopenharmony_ci{
403e5c31af7Sopenharmony_ci}
404e5c31af7Sopenharmony_ci
405e5c31af7Sopenharmony_civoid IndexGroup::init (void)
406e5c31af7Sopenharmony_ci{
407e5c31af7Sopenharmony_ci	struct IndexTest
408e5c31af7Sopenharmony_ci	{
409e5c31af7Sopenharmony_ci		gls::DrawTestSpec::Storage		storage;
410e5c31af7Sopenharmony_ci		gls::DrawTestSpec::IndexType	type;
411e5c31af7Sopenharmony_ci		bool							aligned;
412e5c31af7Sopenharmony_ci		int								offsets[3];
413e5c31af7Sopenharmony_ci	};
414e5c31af7Sopenharmony_ci
415e5c31af7Sopenharmony_ci	const IndexTest tests[] =
416e5c31af7Sopenharmony_ci	{
417e5c31af7Sopenharmony_ci		{ gls::DrawTestSpec::STORAGE_USER,		gls::DrawTestSpec::INDEXTYPE_BYTE,	true,	{ 0, 1, -1 } },
418e5c31af7Sopenharmony_ci		{ gls::DrawTestSpec::STORAGE_USER,		gls::DrawTestSpec::INDEXTYPE_SHORT,	true,	{ 0, 2, -1 } },
419e5c31af7Sopenharmony_ci		{ gls::DrawTestSpec::STORAGE_USER,		gls::DrawTestSpec::INDEXTYPE_INT,	true,	{ 0, 4, -1 } },
420e5c31af7Sopenharmony_ci
421e5c31af7Sopenharmony_ci		{ gls::DrawTestSpec::STORAGE_USER,		gls::DrawTestSpec::INDEXTYPE_SHORT,	false,	{ 1, 3, -1 } },
422e5c31af7Sopenharmony_ci		{ gls::DrawTestSpec::STORAGE_USER,		gls::DrawTestSpec::INDEXTYPE_INT,	false,	{ 2, 3, -1 } },
423e5c31af7Sopenharmony_ci
424e5c31af7Sopenharmony_ci		{ gls::DrawTestSpec::STORAGE_BUFFER,	gls::DrawTestSpec::INDEXTYPE_BYTE,	true,	{ 0, 1, -1 } },
425e5c31af7Sopenharmony_ci		{ gls::DrawTestSpec::STORAGE_BUFFER,	gls::DrawTestSpec::INDEXTYPE_SHORT,	true,	{ 0, 2, -1 } },
426e5c31af7Sopenharmony_ci		{ gls::DrawTestSpec::STORAGE_BUFFER,	gls::DrawTestSpec::INDEXTYPE_INT,	true,	{ 0, 4, -1 } },
427e5c31af7Sopenharmony_ci	};
428e5c31af7Sopenharmony_ci
429e5c31af7Sopenharmony_ci	gls::DrawTestSpec spec;
430e5c31af7Sopenharmony_ci
431e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* userPtrGroup			= new tcu::TestCaseGroup(m_testCtx, "user_ptr", "user pointer");
432e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* unalignedUserPtrGroup	= new tcu::TestCaseGroup(m_testCtx, "unaligned_user_ptr", "unaligned user pointer");
433e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* bufferGroup				= new tcu::TestCaseGroup(m_testCtx, "buffer", "buffer");
434e5c31af7Sopenharmony_ci
435e5c31af7Sopenharmony_ci	genBasicSpec(spec, m_method);
436e5c31af7Sopenharmony_ci
437e5c31af7Sopenharmony_ci	this->addChild(userPtrGroup);
438e5c31af7Sopenharmony_ci	this->addChild(unalignedUserPtrGroup);
439e5c31af7Sopenharmony_ci	this->addChild(bufferGroup);
440e5c31af7Sopenharmony_ci
441e5c31af7Sopenharmony_ci	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
442e5c31af7Sopenharmony_ci	{
443e5c31af7Sopenharmony_ci		const IndexTest&				indexTest	= tests[testNdx];
444e5c31af7Sopenharmony_ci		tcu::TestCaseGroup*				group		= (indexTest.storage == gls::DrawTestSpec::STORAGE_USER)
445e5c31af7Sopenharmony_ci													? ((indexTest.aligned) ? (userPtrGroup) : (unalignedUserPtrGroup))
446e5c31af7Sopenharmony_ci													: ((indexTest.aligned) ? (bufferGroup) : (DE_NULL));
447e5c31af7Sopenharmony_ci
448e5c31af7Sopenharmony_ci		const std::string				name		= std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
449e5c31af7Sopenharmony_ci		const std::string				desc		= std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type) + " in " + gls::DrawTestSpec::storageToString(indexTest.storage);
450e5c31af7Sopenharmony_ci		de::MovePtr<gls::DrawTest>		test		(new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str()));
451e5c31af7Sopenharmony_ci
452e5c31af7Sopenharmony_ci		spec.indexType			= indexTest.type;
453e5c31af7Sopenharmony_ci		spec.indexStorage		= indexTest.storage;
454e5c31af7Sopenharmony_ci
455e5c31af7Sopenharmony_ci		for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
456e5c31af7Sopenharmony_ci		{
457e5c31af7Sopenharmony_ci			const std::string iterationDesc = std::string("offset ") + de::toString(indexTest.offsets[iterationNdx]);
458e5c31af7Sopenharmony_ci			spec.indexPointerOffset	= indexTest.offsets[iterationNdx];
459e5c31af7Sopenharmony_ci			test->addIteration(spec, iterationDesc.c_str());
460e5c31af7Sopenharmony_ci		}
461e5c31af7Sopenharmony_ci
462e5c31af7Sopenharmony_ci		DE_ASSERT(spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET);
463e5c31af7Sopenharmony_ci		DE_ASSERT(spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE);
464e5c31af7Sopenharmony_ci		group->addChild(test.release());
465e5c31af7Sopenharmony_ci	}
466e5c31af7Sopenharmony_ci}
467e5c31af7Sopenharmony_ci
468e5c31af7Sopenharmony_ci
469e5c31af7Sopenharmony_ciclass FirstGroup : public TestCaseGroup
470e5c31af7Sopenharmony_ci{
471e5c31af7Sopenharmony_cipublic:
472e5c31af7Sopenharmony_ci									FirstGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
473e5c31af7Sopenharmony_ci									~FirstGroup		(void);
474e5c31af7Sopenharmony_ci
475e5c31af7Sopenharmony_ci	void							init			(void);
476e5c31af7Sopenharmony_ci
477e5c31af7Sopenharmony_ciprivate:
478e5c31af7Sopenharmony_ci	gls::DrawTestSpec::DrawMethod	m_method;
479e5c31af7Sopenharmony_ci};
480e5c31af7Sopenharmony_ci
481e5c31af7Sopenharmony_ciFirstGroup::FirstGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
482e5c31af7Sopenharmony_ci	: TestCaseGroup		(context, name, descr)
483e5c31af7Sopenharmony_ci	, m_method			(drawMethod)
484e5c31af7Sopenharmony_ci{
485e5c31af7Sopenharmony_ci}
486e5c31af7Sopenharmony_ci
487e5c31af7Sopenharmony_ciFirstGroup::~FirstGroup (void)
488e5c31af7Sopenharmony_ci{
489e5c31af7Sopenharmony_ci}
490e5c31af7Sopenharmony_ci
491e5c31af7Sopenharmony_civoid FirstGroup::init (void)
492e5c31af7Sopenharmony_ci{
493e5c31af7Sopenharmony_ci	const int firsts[] =
494e5c31af7Sopenharmony_ci	{
495e5c31af7Sopenharmony_ci		1, 3, 17
496e5c31af7Sopenharmony_ci	};
497e5c31af7Sopenharmony_ci
498e5c31af7Sopenharmony_ci	gls::DrawTestSpec spec;
499e5c31af7Sopenharmony_ci	genBasicSpec(spec, m_method);
500e5c31af7Sopenharmony_ci
501e5c31af7Sopenharmony_ci	for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); ++firstNdx)
502e5c31af7Sopenharmony_ci	{
503e5c31af7Sopenharmony_ci		const std::string	name = std::string("first_") + de::toString(firsts[firstNdx]);
504e5c31af7Sopenharmony_ci		const std::string	desc = std::string("first ") + de::toString(firsts[firstNdx]);
505e5c31af7Sopenharmony_ci		gls::DrawTest*		test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
506e5c31af7Sopenharmony_ci
507e5c31af7Sopenharmony_ci		spec.first = firsts[firstNdx];
508e5c31af7Sopenharmony_ci
509e5c31af7Sopenharmony_ci		addTestIterations(test, spec, TYPE_DRAW_COUNT);
510e5c31af7Sopenharmony_ci
511e5c31af7Sopenharmony_ci		this->addChild(test);
512e5c31af7Sopenharmony_ci	}
513e5c31af7Sopenharmony_ci}
514e5c31af7Sopenharmony_ci
515e5c31af7Sopenharmony_ciclass MethodGroup : public TestCaseGroup
516e5c31af7Sopenharmony_ci{
517e5c31af7Sopenharmony_cipublic:
518e5c31af7Sopenharmony_ci									MethodGroup			(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
519e5c31af7Sopenharmony_ci									~MethodGroup		(void);
520e5c31af7Sopenharmony_ci
521e5c31af7Sopenharmony_ci	void							init				(void);
522e5c31af7Sopenharmony_ci
523e5c31af7Sopenharmony_ciprivate:
524e5c31af7Sopenharmony_ci	gls::DrawTestSpec::DrawMethod	m_method;
525e5c31af7Sopenharmony_ci};
526e5c31af7Sopenharmony_ci
527e5c31af7Sopenharmony_ciMethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
528e5c31af7Sopenharmony_ci	: TestCaseGroup		(context, name, descr)
529e5c31af7Sopenharmony_ci	, m_method			(drawMethod)
530e5c31af7Sopenharmony_ci{
531e5c31af7Sopenharmony_ci}
532e5c31af7Sopenharmony_ci
533e5c31af7Sopenharmony_ciMethodGroup::~MethodGroup (void)
534e5c31af7Sopenharmony_ci{
535e5c31af7Sopenharmony_ci}
536e5c31af7Sopenharmony_ci
537e5c31af7Sopenharmony_civoid MethodGroup::init (void)
538e5c31af7Sopenharmony_ci{
539e5c31af7Sopenharmony_ci	const bool indexed		= (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED);
540e5c31af7Sopenharmony_ci	const bool hasFirst		= (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED);
541e5c31af7Sopenharmony_ci
542e5c31af7Sopenharmony_ci	const gls::DrawTestSpec::Primitive primitive[] =
543e5c31af7Sopenharmony_ci	{
544e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_POINTS,
545e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
546e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
547e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
548e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_LINES,
549e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
550e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
551e5c31af7Sopenharmony_ci	};
552e5c31af7Sopenharmony_ci
553e5c31af7Sopenharmony_ci	if (hasFirst)
554e5c31af7Sopenharmony_ci	{
555e5c31af7Sopenharmony_ci		// First-tests
556e5c31af7Sopenharmony_ci		this->addChild(new FirstGroup(m_context, "first", "First tests", m_method));
557e5c31af7Sopenharmony_ci	}
558e5c31af7Sopenharmony_ci
559e5c31af7Sopenharmony_ci	if (indexed)
560e5c31af7Sopenharmony_ci	{
561e5c31af7Sopenharmony_ci		// Index-tests
562e5c31af7Sopenharmony_ci		if (m_method != gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED)
563e5c31af7Sopenharmony_ci			this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
564e5c31af7Sopenharmony_ci	}
565e5c31af7Sopenharmony_ci
566e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
567e5c31af7Sopenharmony_ci	{
568e5c31af7Sopenharmony_ci		const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
569e5c31af7Sopenharmony_ci		const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
570e5c31af7Sopenharmony_ci
571e5c31af7Sopenharmony_ci		this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
572e5c31af7Sopenharmony_ci	}
573e5c31af7Sopenharmony_ci}
574e5c31af7Sopenharmony_ci
575e5c31af7Sopenharmony_ciclass GridProgram : public sglr::ShaderProgram
576e5c31af7Sopenharmony_ci{
577e5c31af7Sopenharmony_cipublic:
578e5c31af7Sopenharmony_ci			GridProgram		(void);
579e5c31af7Sopenharmony_ci
580e5c31af7Sopenharmony_ci	void	shadeVertices	(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
581e5c31af7Sopenharmony_ci	void	shadeFragments	(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;
582e5c31af7Sopenharmony_ci};
583e5c31af7Sopenharmony_ci
584e5c31af7Sopenharmony_ciGridProgram::GridProgram (void)
585e5c31af7Sopenharmony_ci	: sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
586e5c31af7Sopenharmony_ci							<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
587e5c31af7Sopenharmony_ci							<< sglr::pdec::VertexAttribute("a_offset", rr::GENERICVECTYPE_FLOAT)
588e5c31af7Sopenharmony_ci							<< sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
589e5c31af7Sopenharmony_ci							<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
590e5c31af7Sopenharmony_ci							<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
591e5c31af7Sopenharmony_ci							<< sglr::pdec::VertexSource("#version 300 es\n"
592e5c31af7Sopenharmony_ci														"in highp vec4 a_position;\n"
593e5c31af7Sopenharmony_ci														"in highp vec4 a_offset;\n"
594e5c31af7Sopenharmony_ci														"in highp vec4 a_color;\n"
595e5c31af7Sopenharmony_ci														"out mediump vec4 v_color;\n"
596e5c31af7Sopenharmony_ci														"void main(void)\n"
597e5c31af7Sopenharmony_ci														"{\n"
598e5c31af7Sopenharmony_ci														"	gl_Position = a_position + a_offset;\n"
599e5c31af7Sopenharmony_ci														"	v_color = a_color;\n"
600e5c31af7Sopenharmony_ci														"}\n")
601e5c31af7Sopenharmony_ci							<< sglr::pdec::FragmentSource(
602e5c31af7Sopenharmony_ci														"#version 300 es\n"
603e5c31af7Sopenharmony_ci														"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
604e5c31af7Sopenharmony_ci														"in mediump vec4 v_color;\n"
605e5c31af7Sopenharmony_ci														"void main(void)\n"
606e5c31af7Sopenharmony_ci														"{\n"
607e5c31af7Sopenharmony_ci														"	dEQP_FragColor = v_color;\n"
608e5c31af7Sopenharmony_ci														"}\n"))
609e5c31af7Sopenharmony_ci{
610e5c31af7Sopenharmony_ci}
611e5c31af7Sopenharmony_ci
612e5c31af7Sopenharmony_civoid GridProgram::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
613e5c31af7Sopenharmony_ci{
614e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < numPackets; ++ndx)
615e5c31af7Sopenharmony_ci	{
616e5c31af7Sopenharmony_ci		packets[ndx]->position = rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx) + rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
617e5c31af7Sopenharmony_ci		packets[ndx]->outputs[0] = rr::readVertexAttribFloat(inputs[2], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
618e5c31af7Sopenharmony_ci	}
619e5c31af7Sopenharmony_ci}
620e5c31af7Sopenharmony_ci
621e5c31af7Sopenharmony_civoid GridProgram::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
622e5c31af7Sopenharmony_ci{
623e5c31af7Sopenharmony_ci	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
624e5c31af7Sopenharmony_ci	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
625e5c31af7Sopenharmony_ci		rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx));
626e5c31af7Sopenharmony_ci}
627e5c31af7Sopenharmony_ci
628e5c31af7Sopenharmony_ciclass InstancedGridRenderTest : public TestCase
629e5c31af7Sopenharmony_ci{
630e5c31af7Sopenharmony_cipublic:
631e5c31af7Sopenharmony_ci					InstancedGridRenderTest		(Context& context, const char* name, const char* desc, int gridSide, bool useIndices);
632e5c31af7Sopenharmony_ci					~InstancedGridRenderTest	(void);
633e5c31af7Sopenharmony_ci
634e5c31af7Sopenharmony_ci	IterateResult	iterate						(void);
635e5c31af7Sopenharmony_ci
636e5c31af7Sopenharmony_ciprivate:
637e5c31af7Sopenharmony_ci	void			renderTo					(sglr::Context& ctx, sglr::ShaderProgram& program, tcu::Surface& dst);
638e5c31af7Sopenharmony_ci	bool			verifyImage					(const tcu::Surface& image);
639e5c31af7Sopenharmony_ci
640e5c31af7Sopenharmony_ci	const int		m_gridSide;
641e5c31af7Sopenharmony_ci	const bool		m_useIndices;
642e5c31af7Sopenharmony_ci};
643e5c31af7Sopenharmony_ci
644e5c31af7Sopenharmony_ciInstancedGridRenderTest::InstancedGridRenderTest (Context& context, const char* name, const char* desc, int gridSide, bool useIndices)
645e5c31af7Sopenharmony_ci	: TestCase		(context, name, desc)
646e5c31af7Sopenharmony_ci	, m_gridSide	(gridSide)
647e5c31af7Sopenharmony_ci	, m_useIndices	(useIndices)
648e5c31af7Sopenharmony_ci{
649e5c31af7Sopenharmony_ci}
650e5c31af7Sopenharmony_ci
651e5c31af7Sopenharmony_ciInstancedGridRenderTest::~InstancedGridRenderTest (void)
652e5c31af7Sopenharmony_ci{
653e5c31af7Sopenharmony_ci}
654e5c31af7Sopenharmony_ci
655e5c31af7Sopenharmony_ciInstancedGridRenderTest::IterateResult InstancedGridRenderTest::iterate (void)
656e5c31af7Sopenharmony_ci{
657e5c31af7Sopenharmony_ci	const int renderTargetWidth  = de::min(1024, m_context.getRenderTarget().getWidth());
658e5c31af7Sopenharmony_ci	const int renderTargetHeight = de::min(1024, m_context.getRenderTarget().getHeight());
659e5c31af7Sopenharmony_ci
660e5c31af7Sopenharmony_ci	sglr::GLContext ctx		(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS, tcu::IVec4(0, 0, renderTargetWidth, renderTargetHeight));
661e5c31af7Sopenharmony_ci	tcu::Surface	surface	(renderTargetWidth, renderTargetHeight);
662e5c31af7Sopenharmony_ci	GridProgram		program;
663e5c31af7Sopenharmony_ci
664e5c31af7Sopenharmony_ci	// render
665e5c31af7Sopenharmony_ci
666e5c31af7Sopenharmony_ci	renderTo(ctx, program, surface);
667e5c31af7Sopenharmony_ci
668e5c31af7Sopenharmony_ci	// verify image
669e5c31af7Sopenharmony_ci
670e5c31af7Sopenharmony_ci	if (verifyImage(surface))
671e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
672e5c31af7Sopenharmony_ci	else
673e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rendering result");
674e5c31af7Sopenharmony_ci	return STOP;
675e5c31af7Sopenharmony_ci}
676e5c31af7Sopenharmony_ci
677e5c31af7Sopenharmony_civoid InstancedGridRenderTest::renderTo (sglr::Context& ctx, sglr::ShaderProgram& program, tcu::Surface& dst)
678e5c31af7Sopenharmony_ci{
679e5c31af7Sopenharmony_ci	const tcu::Vec4 green	(0, 1, 0, 1);
680e5c31af7Sopenharmony_ci	const tcu::Vec4 yellow	(1, 1, 0, 1);
681e5c31af7Sopenharmony_ci
682e5c31af7Sopenharmony_ci	deUint32 positionBuf	= 0;
683e5c31af7Sopenharmony_ci	deUint32 offsetBuf		= 0;
684e5c31af7Sopenharmony_ci	deUint32 colorBuf		= 0;
685e5c31af7Sopenharmony_ci	deUint32 indexBuf		= 0;
686e5c31af7Sopenharmony_ci	deUint32 programID		= ctx.createProgram(&program);
687e5c31af7Sopenharmony_ci	deInt32 posLocation		= ctx.getAttribLocation(programID, "a_position");
688e5c31af7Sopenharmony_ci	deInt32 offsetLocation	= ctx.getAttribLocation(programID, "a_offset");
689e5c31af7Sopenharmony_ci	deInt32 colorLocation	= ctx.getAttribLocation(programID, "a_color");
690e5c31af7Sopenharmony_ci
691e5c31af7Sopenharmony_ci	float cellW	= 2.0f / (float)m_gridSide;
692e5c31af7Sopenharmony_ci	float cellH	= 2.0f / (float)m_gridSide;
693e5c31af7Sopenharmony_ci	const tcu::Vec4 vertexPositions[] =
694e5c31af7Sopenharmony_ci	{
695e5c31af7Sopenharmony_ci		tcu::Vec4(0,		0,		0, 1),
696e5c31af7Sopenharmony_ci		tcu::Vec4(cellW,	0,		0, 1),
697e5c31af7Sopenharmony_ci		tcu::Vec4(0,		cellH,	0, 1),
698e5c31af7Sopenharmony_ci
699e5c31af7Sopenharmony_ci		tcu::Vec4(0,		cellH,	0, 1),
700e5c31af7Sopenharmony_ci		tcu::Vec4(cellW,	0,		0, 1),
701e5c31af7Sopenharmony_ci		tcu::Vec4(cellW,	cellH,	0, 1),
702e5c31af7Sopenharmony_ci	};
703e5c31af7Sopenharmony_ci
704e5c31af7Sopenharmony_ci	const deUint16 indices[] =
705e5c31af7Sopenharmony_ci	{
706e5c31af7Sopenharmony_ci		0, 4, 3,
707e5c31af7Sopenharmony_ci		2, 1, 5
708e5c31af7Sopenharmony_ci	};
709e5c31af7Sopenharmony_ci
710e5c31af7Sopenharmony_ci	std::vector<tcu::Vec4> offsets;
711e5c31af7Sopenharmony_ci	for (int x = 0; x < m_gridSide; ++x)
712e5c31af7Sopenharmony_ci	for (int y = 0; y < m_gridSide; ++y)
713e5c31af7Sopenharmony_ci		offsets.push_back(tcu::Vec4((float)x * cellW - 1.0f, (float)y * cellW - 1.0f, 0, 0));
714e5c31af7Sopenharmony_ci
715e5c31af7Sopenharmony_ci	std::vector<tcu::Vec4> colors;
716e5c31af7Sopenharmony_ci	for (int x = 0; x < m_gridSide; ++x)
717e5c31af7Sopenharmony_ci	for (int y = 0; y < m_gridSide; ++y)
718e5c31af7Sopenharmony_ci		colors.push_back(((x + y) % 2 == 0) ? (green) : (yellow));
719e5c31af7Sopenharmony_ci
720e5c31af7Sopenharmony_ci	ctx.genBuffers(1, &positionBuf);
721e5c31af7Sopenharmony_ci	ctx.bindBuffer(GL_ARRAY_BUFFER, positionBuf);
722e5c31af7Sopenharmony_ci	ctx.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
723e5c31af7Sopenharmony_ci	ctx.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
724e5c31af7Sopenharmony_ci	ctx.vertexAttribDivisor(posLocation, 0);
725e5c31af7Sopenharmony_ci	ctx.enableVertexAttribArray(posLocation);
726e5c31af7Sopenharmony_ci
727e5c31af7Sopenharmony_ci	ctx.genBuffers(1, &offsetBuf);
728e5c31af7Sopenharmony_ci	ctx.bindBuffer(GL_ARRAY_BUFFER, offsetBuf);
729e5c31af7Sopenharmony_ci	ctx.bufferData(GL_ARRAY_BUFFER, offsets.size() * sizeof(tcu::Vec4), &offsets[0], GL_STATIC_DRAW);
730e5c31af7Sopenharmony_ci	ctx.vertexAttribPointer(offsetLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
731e5c31af7Sopenharmony_ci	ctx.vertexAttribDivisor(offsetLocation, 1);
732e5c31af7Sopenharmony_ci	ctx.enableVertexAttribArray(offsetLocation);
733e5c31af7Sopenharmony_ci
734e5c31af7Sopenharmony_ci	ctx.genBuffers(1, &colorBuf);
735e5c31af7Sopenharmony_ci	ctx.bindBuffer(GL_ARRAY_BUFFER, colorBuf);
736e5c31af7Sopenharmony_ci	ctx.bufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(tcu::Vec4), &colors[0], GL_STATIC_DRAW);
737e5c31af7Sopenharmony_ci	ctx.vertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
738e5c31af7Sopenharmony_ci	ctx.vertexAttribDivisor(colorLocation, 1);
739e5c31af7Sopenharmony_ci	ctx.enableVertexAttribArray(colorLocation);
740e5c31af7Sopenharmony_ci
741e5c31af7Sopenharmony_ci	if (m_useIndices)
742e5c31af7Sopenharmony_ci	{
743e5c31af7Sopenharmony_ci		ctx.genBuffers(1, &indexBuf);
744e5c31af7Sopenharmony_ci		ctx.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
745e5c31af7Sopenharmony_ci		ctx.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
746e5c31af7Sopenharmony_ci	}
747e5c31af7Sopenharmony_ci
748e5c31af7Sopenharmony_ci	ctx.clearColor(0, 0, 0, 1);
749e5c31af7Sopenharmony_ci	ctx.clear(GL_COLOR_BUFFER_BIT);
750e5c31af7Sopenharmony_ci
751e5c31af7Sopenharmony_ci	ctx.viewport(0, 0, dst.getWidth(), dst.getHeight());
752e5c31af7Sopenharmony_ci
753e5c31af7Sopenharmony_ci	ctx.useProgram(programID);
754e5c31af7Sopenharmony_ci	if (m_useIndices)
755e5c31af7Sopenharmony_ci		ctx.drawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL, m_gridSide * m_gridSide);
756e5c31af7Sopenharmony_ci	else
757e5c31af7Sopenharmony_ci		ctx.drawArraysInstanced(GL_TRIANGLES, 0, 6, m_gridSide * m_gridSide);
758e5c31af7Sopenharmony_ci	ctx.useProgram(0);
759e5c31af7Sopenharmony_ci
760e5c31af7Sopenharmony_ci	if (m_useIndices)
761e5c31af7Sopenharmony_ci		ctx.deleteBuffers(1, &indexBuf);
762e5c31af7Sopenharmony_ci	ctx.deleteBuffers(1, &colorBuf);
763e5c31af7Sopenharmony_ci	ctx.deleteBuffers(1, &offsetBuf);
764e5c31af7Sopenharmony_ci	ctx.deleteBuffers(1, &positionBuf);
765e5c31af7Sopenharmony_ci	ctx.deleteProgram(programID);
766e5c31af7Sopenharmony_ci
767e5c31af7Sopenharmony_ci	ctx.finish();
768e5c31af7Sopenharmony_ci	ctx.readPixels(dst, 0, 0, dst.getWidth(), dst.getHeight());
769e5c31af7Sopenharmony_ci
770e5c31af7Sopenharmony_ci	glu::checkError(ctx.getError(), "", __FILE__, __LINE__);
771e5c31af7Sopenharmony_ci}
772e5c31af7Sopenharmony_ci
773e5c31af7Sopenharmony_cibool InstancedGridRenderTest::verifyImage (const tcu::Surface& image)
774e5c31af7Sopenharmony_ci{
775e5c31af7Sopenharmony_ci	// \note the green/yellow pattern is only for clarity. The test will only verify that all instances were drawn by looking for anything non-green/yellow.
776e5c31af7Sopenharmony_ci	using tcu::TestLog;
777e5c31af7Sopenharmony_ci
778e5c31af7Sopenharmony_ci	const int colorThreshold	= 20;
779e5c31af7Sopenharmony_ci
780e5c31af7Sopenharmony_ci	tcu::Surface error			(image.getWidth(), image.getHeight());
781e5c31af7Sopenharmony_ci	bool isOk					= true;
782e5c31af7Sopenharmony_ci
783e5c31af7Sopenharmony_ci	for (int y = 0; y < image.getHeight(); y++)
784e5c31af7Sopenharmony_ci	for (int x = 0; x < image.getWidth(); x++)
785e5c31af7Sopenharmony_ci	{
786e5c31af7Sopenharmony_ci		if (x == 0 || y == 0 || y + 1 == image.getHeight() || x + 1 == image.getWidth())
787e5c31af7Sopenharmony_ci		{
788e5c31af7Sopenharmony_ci			// Background color might bleed in at the borders with msaa
789e5c31af7Sopenharmony_ci			error.setPixel(x, y, tcu::RGBA(0, 255, 0, 255));
790e5c31af7Sopenharmony_ci		}
791e5c31af7Sopenharmony_ci		else
792e5c31af7Sopenharmony_ci		{
793e5c31af7Sopenharmony_ci			const tcu::RGBA pixel = image.getPixel(x, y);
794e5c31af7Sopenharmony_ci			bool pixelOk = true;
795e5c31af7Sopenharmony_ci
796e5c31af7Sopenharmony_ci			// Any pixel with !(G ~= 255) is faulty (not a linear combinations of green and yellow)
797e5c31af7Sopenharmony_ci			if (de::abs(pixel.getGreen() - 255) > colorThreshold)
798e5c31af7Sopenharmony_ci				pixelOk = false;
799e5c31af7Sopenharmony_ci
800e5c31af7Sopenharmony_ci			// Any pixel with !(B ~= 0) is faulty (not a linear combinations of green and yellow)
801e5c31af7Sopenharmony_ci			if (de::abs(pixel.getBlue() - 0) > colorThreshold)
802e5c31af7Sopenharmony_ci				pixelOk = false;
803e5c31af7Sopenharmony_ci
804e5c31af7Sopenharmony_ci			error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255)));
805e5c31af7Sopenharmony_ci			isOk = isOk && pixelOk;
806e5c31af7Sopenharmony_ci		}
807e5c31af7Sopenharmony_ci	}
808e5c31af7Sopenharmony_ci
809e5c31af7Sopenharmony_ci	if (!isOk)
810e5c31af7Sopenharmony_ci	{
811e5c31af7Sopenharmony_ci		tcu::TestLog& log = m_testCtx.getLog();
812e5c31af7Sopenharmony_ci
813e5c31af7Sopenharmony_ci		log << TestLog::Message << "Image verification failed." << TestLog::EndMessage;
814e5c31af7Sopenharmony_ci		log << TestLog::ImageSet("Verfication result", "Result of rendering")
815e5c31af7Sopenharmony_ci			<< TestLog::Image("Result",		"Result",		image)
816e5c31af7Sopenharmony_ci			<< TestLog::Image("ErrorMask",	"Error mask",	error)
817e5c31af7Sopenharmony_ci			<< TestLog::EndImageSet;
818e5c31af7Sopenharmony_ci	}
819e5c31af7Sopenharmony_ci	else
820e5c31af7Sopenharmony_ci	{
821e5c31af7Sopenharmony_ci		tcu::TestLog& log = m_testCtx.getLog();
822e5c31af7Sopenharmony_ci
823e5c31af7Sopenharmony_ci		log << TestLog::ImageSet("Verfication result", "Result of rendering")
824e5c31af7Sopenharmony_ci			<< TestLog::Image("Result", "Result", image)
825e5c31af7Sopenharmony_ci			<< TestLog::EndImageSet;
826e5c31af7Sopenharmony_ci	}
827e5c31af7Sopenharmony_ci
828e5c31af7Sopenharmony_ci	return isOk;
829e5c31af7Sopenharmony_ci}
830e5c31af7Sopenharmony_ci
831e5c31af7Sopenharmony_ciclass InstancingGroup : public TestCaseGroup
832e5c31af7Sopenharmony_ci{
833e5c31af7Sopenharmony_cipublic:
834e5c31af7Sopenharmony_ci									InstancingGroup		(Context& context, const char* name, const char* descr);
835e5c31af7Sopenharmony_ci									~InstancingGroup	(void);
836e5c31af7Sopenharmony_ci
837e5c31af7Sopenharmony_ci	void							init				(void);
838e5c31af7Sopenharmony_ci};
839e5c31af7Sopenharmony_ci
840e5c31af7Sopenharmony_ciInstancingGroup::InstancingGroup (Context& context, const char* name, const char* descr)
841e5c31af7Sopenharmony_ci	: TestCaseGroup	(context, name, descr)
842e5c31af7Sopenharmony_ci{
843e5c31af7Sopenharmony_ci}
844e5c31af7Sopenharmony_ci
845e5c31af7Sopenharmony_ciInstancingGroup::~InstancingGroup (void)
846e5c31af7Sopenharmony_ci{
847e5c31af7Sopenharmony_ci}
848e5c31af7Sopenharmony_ci
849e5c31af7Sopenharmony_civoid InstancingGroup::init (void)
850e5c31af7Sopenharmony_ci{
851e5c31af7Sopenharmony_ci	const int gridWidths[] =
852e5c31af7Sopenharmony_ci	{
853e5c31af7Sopenharmony_ci		2,
854e5c31af7Sopenharmony_ci		5,
855e5c31af7Sopenharmony_ci		10,
856e5c31af7Sopenharmony_ci		32,
857e5c31af7Sopenharmony_ci		100,
858e5c31af7Sopenharmony_ci	};
859e5c31af7Sopenharmony_ci
860e5c31af7Sopenharmony_ci	// drawArrays
861e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(gridWidths); ++ndx)
862e5c31af7Sopenharmony_ci	{
863e5c31af7Sopenharmony_ci		const std::string name = std::string("draw_arrays_instanced_grid_") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);
864e5c31af7Sopenharmony_ci		const std::string desc = std::string("DrawArraysInstanced, Grid size ") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);
865e5c31af7Sopenharmony_ci
866e5c31af7Sopenharmony_ci		this->addChild(new InstancedGridRenderTest(m_context, name.c_str(), desc.c_str(), gridWidths[ndx], false));
867e5c31af7Sopenharmony_ci	}
868e5c31af7Sopenharmony_ci
869e5c31af7Sopenharmony_ci	// drawElements
870e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(gridWidths); ++ndx)
871e5c31af7Sopenharmony_ci	{
872e5c31af7Sopenharmony_ci		const std::string name = std::string("draw_elements_instanced_grid_") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);
873e5c31af7Sopenharmony_ci		const std::string desc = std::string("DrawElementsInstanced, Grid size ") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);
874e5c31af7Sopenharmony_ci
875e5c31af7Sopenharmony_ci		this->addChild(new InstancedGridRenderTest(m_context, name.c_str(), desc.c_str(), gridWidths[ndx], true));
876e5c31af7Sopenharmony_ci	}
877e5c31af7Sopenharmony_ci}
878e5c31af7Sopenharmony_ci
879e5c31af7Sopenharmony_ciclass RandomGroup : public TestCaseGroup
880e5c31af7Sopenharmony_ci{
881e5c31af7Sopenharmony_cipublic:
882e5c31af7Sopenharmony_ci									RandomGroup		(Context& context, const char* name, const char* descr);
883e5c31af7Sopenharmony_ci									~RandomGroup	(void);
884e5c31af7Sopenharmony_ci
885e5c31af7Sopenharmony_ci	void							init			(void);
886e5c31af7Sopenharmony_ci};
887e5c31af7Sopenharmony_ci
888e5c31af7Sopenharmony_citemplate <int SIZE>
889e5c31af7Sopenharmony_cistruct UniformWeightArray
890e5c31af7Sopenharmony_ci{
891e5c31af7Sopenharmony_ci	float weights[SIZE];
892e5c31af7Sopenharmony_ci
893e5c31af7Sopenharmony_ci	UniformWeightArray (void)
894e5c31af7Sopenharmony_ci	{
895e5c31af7Sopenharmony_ci		for (int i=0; i<SIZE; ++i)
896e5c31af7Sopenharmony_ci			weights[i] = 1.0f;
897e5c31af7Sopenharmony_ci	}
898e5c31af7Sopenharmony_ci};
899e5c31af7Sopenharmony_ci
900e5c31af7Sopenharmony_ciRandomGroup::RandomGroup (Context& context, const char* name, const char* descr)
901e5c31af7Sopenharmony_ci	: TestCaseGroup	(context, name, descr)
902e5c31af7Sopenharmony_ci{
903e5c31af7Sopenharmony_ci}
904e5c31af7Sopenharmony_ci
905e5c31af7Sopenharmony_ciRandomGroup::~RandomGroup (void)
906e5c31af7Sopenharmony_ci{
907e5c31af7Sopenharmony_ci}
908e5c31af7Sopenharmony_ci
909e5c31af7Sopenharmony_civoid RandomGroup::init (void)
910e5c31af7Sopenharmony_ci{
911e5c31af7Sopenharmony_ci	const int			numAttempts				= 300;
912e5c31af7Sopenharmony_ci
913e5c31af7Sopenharmony_ci	static const int	attribCounts[]			= { 1, 2, 5 };
914e5c31af7Sopenharmony_ci	static const float	attribWeights[]			= { 30, 10, 1 };
915e5c31af7Sopenharmony_ci	static const int	primitiveCounts[]		= { 1, 5, 64 };
916e5c31af7Sopenharmony_ci	static const float	primitiveCountWeights[]	= { 20, 10, 1 };
917e5c31af7Sopenharmony_ci	static const int	indexOffsets[]			= { 0, 7, 13 };
918e5c31af7Sopenharmony_ci	static const float	indexOffsetWeights[]	= { 20, 20, 1 };
919e5c31af7Sopenharmony_ci	static const int	firsts[]				= { 0, 7, 13 };
920e5c31af7Sopenharmony_ci	static const float	firstWeights[]			= { 20, 20, 1 };
921e5c31af7Sopenharmony_ci	static const int	instanceCounts[]		= { 1, 2, 16, 17 };
922e5c31af7Sopenharmony_ci	static const float	instanceWeights[]		= { 20, 10, 5, 1 };
923e5c31af7Sopenharmony_ci	static const int	indexMins[]				= { 0, 1, 3, 8 };
924e5c31af7Sopenharmony_ci	static const int	indexMaxs[]				= { 4, 8, 128, 257 };
925e5c31af7Sopenharmony_ci	static const float	indexWeights[]			= { 50, 50, 50, 50 };
926e5c31af7Sopenharmony_ci	static const int	offsets[]				= { 0, 1, 5, 12 };
927e5c31af7Sopenharmony_ci	static const float	offsetWeights[]			= { 50, 10, 10, 10 };
928e5c31af7Sopenharmony_ci	static const int	strides[]				= { 0, 7, 16, 17 };
929e5c31af7Sopenharmony_ci	static const float	strideWeights[]			= { 50, 10, 10, 10 };
930e5c31af7Sopenharmony_ci	static const int	instanceDivisors[]		= { 0, 1, 3, 129 };
931e5c31af7Sopenharmony_ci	static const float	instanceDivisorWeights[]= { 70, 30, 10, 10 };
932e5c31af7Sopenharmony_ci
933e5c31af7Sopenharmony_ci	static const gls::DrawTestSpec::Primitive primitives[] =
934e5c31af7Sopenharmony_ci	{
935e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_POINTS,
936e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
937e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
938e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
939e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_LINES,
940e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
941e5c31af7Sopenharmony_ci		gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
942e5c31af7Sopenharmony_ci	};
943e5c31af7Sopenharmony_ci	const UniformWeightArray<DE_LENGTH_OF_ARRAY(primitives)> primitiveWeights;
944e5c31af7Sopenharmony_ci
945e5c31af7Sopenharmony_ci	static const gls::DrawTestSpec::DrawMethod drawMethods[] =
946e5c31af7Sopenharmony_ci	{
947e5c31af7Sopenharmony_ci		gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS,
948e5c31af7Sopenharmony_ci		gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED,
949e5c31af7Sopenharmony_ci		gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS,
950e5c31af7Sopenharmony_ci		gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED,
951e5c31af7Sopenharmony_ci		gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED
952e5c31af7Sopenharmony_ci	};
953e5c31af7Sopenharmony_ci	const UniformWeightArray<DE_LENGTH_OF_ARRAY(drawMethods)> drawMethodWeights;
954e5c31af7Sopenharmony_ci
955e5c31af7Sopenharmony_ci	static const gls::DrawTestSpec::IndexType indexTypes[] =
956e5c31af7Sopenharmony_ci	{
957e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INDEXTYPE_BYTE,
958e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INDEXTYPE_SHORT,
959e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INDEXTYPE_INT,
960e5c31af7Sopenharmony_ci	};
961e5c31af7Sopenharmony_ci	const UniformWeightArray<DE_LENGTH_OF_ARRAY(indexTypes)> indexTypeWeights;
962e5c31af7Sopenharmony_ci
963e5c31af7Sopenharmony_ci	static const gls::DrawTestSpec::Storage storages[] =
964e5c31af7Sopenharmony_ci	{
965e5c31af7Sopenharmony_ci		gls::DrawTestSpec::STORAGE_USER,
966e5c31af7Sopenharmony_ci		gls::DrawTestSpec::STORAGE_BUFFER,
967e5c31af7Sopenharmony_ci	};
968e5c31af7Sopenharmony_ci	const UniformWeightArray<DE_LENGTH_OF_ARRAY(storages)> storageWeights;
969e5c31af7Sopenharmony_ci
970e5c31af7Sopenharmony_ci	static const gls::DrawTestSpec::InputType inputTypes[] =
971e5c31af7Sopenharmony_ci	{
972e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_FLOAT,
973e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_FIXED,
974e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_BYTE,
975e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_SHORT,
976e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE,
977e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT,
978e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_INT,
979e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT,
980e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_HALF,
981e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10,
982e5c31af7Sopenharmony_ci		gls::DrawTestSpec::INPUTTYPE_INT_2_10_10_10,
983e5c31af7Sopenharmony_ci	};
984e5c31af7Sopenharmony_ci	const UniformWeightArray<DE_LENGTH_OF_ARRAY(inputTypes)> inputTypeWeights;
985e5c31af7Sopenharmony_ci
986e5c31af7Sopenharmony_ci	static const gls::DrawTestSpec::OutputType outputTypes[] =
987e5c31af7Sopenharmony_ci	{
988e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_FLOAT,
989e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_VEC2,
990e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_VEC3,
991e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_VEC4,
992e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_INT,
993e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_UINT,
994e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_IVEC2,
995e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_IVEC3,
996e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_IVEC4,
997e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_UVEC2,
998e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_UVEC3,
999e5c31af7Sopenharmony_ci		gls::DrawTestSpec::OUTPUTTYPE_UVEC4,
1000e5c31af7Sopenharmony_ci	};
1001e5c31af7Sopenharmony_ci	const UniformWeightArray<DE_LENGTH_OF_ARRAY(outputTypes)> outputTypeWeights;
1002e5c31af7Sopenharmony_ci
1003e5c31af7Sopenharmony_ci	static const gls::DrawTestSpec::Usage usages[] =
1004e5c31af7Sopenharmony_ci	{
1005e5c31af7Sopenharmony_ci		gls::DrawTestSpec::USAGE_DYNAMIC_DRAW,
1006e5c31af7Sopenharmony_ci		gls::DrawTestSpec::USAGE_STATIC_DRAW,
1007e5c31af7Sopenharmony_ci		gls::DrawTestSpec::USAGE_STREAM_DRAW,
1008e5c31af7Sopenharmony_ci		gls::DrawTestSpec::USAGE_STREAM_READ,
1009e5c31af7Sopenharmony_ci		gls::DrawTestSpec::USAGE_STREAM_COPY,
1010e5c31af7Sopenharmony_ci		gls::DrawTestSpec::USAGE_STATIC_READ,
1011e5c31af7Sopenharmony_ci		gls::DrawTestSpec::USAGE_STATIC_COPY,
1012e5c31af7Sopenharmony_ci		gls::DrawTestSpec::USAGE_DYNAMIC_READ,
1013e5c31af7Sopenharmony_ci		gls::DrawTestSpec::USAGE_DYNAMIC_COPY,
1014e5c31af7Sopenharmony_ci	};
1015e5c31af7Sopenharmony_ci	const UniformWeightArray<DE_LENGTH_OF_ARRAY(usages)> usageWeights;
1016e5c31af7Sopenharmony_ci
1017e5c31af7Sopenharmony_ci	static const deUint32 disallowedCases[]=
1018e5c31af7Sopenharmony_ci	{
1019e5c31af7Sopenharmony_ci		544,	//!< extremely narrow triangle
1020e5c31af7Sopenharmony_ci	};
1021e5c31af7Sopenharmony_ci
1022e5c31af7Sopenharmony_ci	std::set<deUint32>	insertedHashes;
1023e5c31af7Sopenharmony_ci	size_t				insertedCount = 0;
1024e5c31af7Sopenharmony_ci
1025e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < numAttempts; ++ndx)
1026e5c31af7Sopenharmony_ci	{
1027e5c31af7Sopenharmony_ci		de::Random random(0xc551393 + ndx); // random does not depend on previous cases
1028e5c31af7Sopenharmony_ci
1029e5c31af7Sopenharmony_ci		int					attributeCount = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(attribCounts), DE_ARRAY_END(attribCounts), attribWeights);
1030e5c31af7Sopenharmony_ci		gls::DrawTestSpec	spec;
1031e5c31af7Sopenharmony_ci
1032e5c31af7Sopenharmony_ci		spec.apiType				= glu::ApiType::es(3,0);
1033e5c31af7Sopenharmony_ci		spec.primitive				= random.chooseWeighted<gls::DrawTestSpec::Primitive>	(DE_ARRAY_BEGIN(primitives),		DE_ARRAY_END(primitives),		primitiveWeights.weights);
1034e5c31af7Sopenharmony_ci		spec.primitiveCount			= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(primitiveCounts),	DE_ARRAY_END(primitiveCounts),	primitiveCountWeights);
1035e5c31af7Sopenharmony_ci		spec.drawMethod				= random.chooseWeighted<gls::DrawTestSpec::DrawMethod>	(DE_ARRAY_BEGIN(drawMethods),		DE_ARRAY_END(drawMethods),		drawMethodWeights.weights);
1036e5c31af7Sopenharmony_ci		spec.indexType				= random.chooseWeighted<gls::DrawTestSpec::IndexType>	(DE_ARRAY_BEGIN(indexTypes),		DE_ARRAY_END(indexTypes),		indexTypeWeights.weights);
1037e5c31af7Sopenharmony_ci		spec.indexPointerOffset		= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indexOffsets),		DE_ARRAY_END(indexOffsets),		indexOffsetWeights);
1038e5c31af7Sopenharmony_ci		spec.indexStorage			= random.chooseWeighted<gls::DrawTestSpec::Storage>		(DE_ARRAY_BEGIN(storages),			DE_ARRAY_END(storages),			storageWeights.weights);
1039e5c31af7Sopenharmony_ci		spec.first					= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(firsts),			DE_ARRAY_END(firsts),			firstWeights);
1040e5c31af7Sopenharmony_ci		spec.indexMin				= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indexMins),			DE_ARRAY_END(indexMins),		indexWeights);
1041e5c31af7Sopenharmony_ci		spec.indexMax				= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indexMaxs),			DE_ARRAY_END(indexMaxs),		indexWeights);
1042e5c31af7Sopenharmony_ci		spec.instanceCount			= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(instanceCounts),	DE_ARRAY_END(instanceCounts),	instanceWeights);
1043e5c31af7Sopenharmony_ci
1044e5c31af7Sopenharmony_ci		// check spec is legal
1045e5c31af7Sopenharmony_ci		if (!spec.valid())
1046e5c31af7Sopenharmony_ci			continue;
1047e5c31af7Sopenharmony_ci
1048e5c31af7Sopenharmony_ci		for (int attrNdx = 0; attrNdx < attributeCount;)
1049e5c31af7Sopenharmony_ci		{
1050e5c31af7Sopenharmony_ci			bool valid;
1051e5c31af7Sopenharmony_ci			gls::DrawTestSpec::AttributeSpec attribSpec;
1052e5c31af7Sopenharmony_ci
1053e5c31af7Sopenharmony_ci			attribSpec.inputType			= random.chooseWeighted<gls::DrawTestSpec::InputType>	(DE_ARRAY_BEGIN(inputTypes),		DE_ARRAY_END(inputTypes),		inputTypeWeights.weights);
1054e5c31af7Sopenharmony_ci			attribSpec.outputType			= random.chooseWeighted<gls::DrawTestSpec::OutputType>	(DE_ARRAY_BEGIN(outputTypes),		DE_ARRAY_END(outputTypes),		outputTypeWeights.weights);
1055e5c31af7Sopenharmony_ci			attribSpec.storage				= random.chooseWeighted<gls::DrawTestSpec::Storage>		(DE_ARRAY_BEGIN(storages),			DE_ARRAY_END(storages),			storageWeights.weights);
1056e5c31af7Sopenharmony_ci			attribSpec.usage				= random.chooseWeighted<gls::DrawTestSpec::Usage>		(DE_ARRAY_BEGIN(usages),			DE_ARRAY_END(usages),			usageWeights.weights);
1057e5c31af7Sopenharmony_ci			attribSpec.componentCount		= random.getInt(1, 4);
1058e5c31af7Sopenharmony_ci			attribSpec.offset				= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(offsets), DE_ARRAY_END(offsets), offsetWeights);
1059e5c31af7Sopenharmony_ci			attribSpec.stride				= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(strides), DE_ARRAY_END(strides), strideWeights);
1060e5c31af7Sopenharmony_ci			attribSpec.normalize			= random.getBool();
1061e5c31af7Sopenharmony_ci			attribSpec.instanceDivisor		= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(instanceDivisors), DE_ARRAY_END(instanceDivisors), instanceDivisorWeights);
1062e5c31af7Sopenharmony_ci			attribSpec.useDefaultAttribute	= random.getBool();
1063e5c31af7Sopenharmony_ci
1064e5c31af7Sopenharmony_ci			// check spec is legal
1065e5c31af7Sopenharmony_ci			valid = attribSpec.valid(spec.apiType);
1066e5c31af7Sopenharmony_ci
1067e5c31af7Sopenharmony_ci			// we do not want interleaved elements. (Might result in some weird floating point values)
1068e5c31af7Sopenharmony_ci			if (attribSpec.stride && attribSpec.componentCount * gls::DrawTestSpec::inputTypeSize(attribSpec.inputType) > attribSpec.stride)
1069e5c31af7Sopenharmony_ci				valid = false;
1070e5c31af7Sopenharmony_ci
1071e5c31af7Sopenharmony_ci			// try again if not valid
1072e5c31af7Sopenharmony_ci			if (valid)
1073e5c31af7Sopenharmony_ci			{
1074e5c31af7Sopenharmony_ci				spec.attribs.push_back(attribSpec);
1075e5c31af7Sopenharmony_ci				++attrNdx;
1076e5c31af7Sopenharmony_ci			}
1077e5c31af7Sopenharmony_ci		}
1078e5c31af7Sopenharmony_ci
1079e5c31af7Sopenharmony_ci		// Do not collapse all vertex positions to a single positions
1080e5c31af7Sopenharmony_ci		if (spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
1081e5c31af7Sopenharmony_ci			spec.attribs[0].instanceDivisor = 0;
1082e5c31af7Sopenharmony_ci
1083e5c31af7Sopenharmony_ci		// Is render result meaningful?
1084e5c31af7Sopenharmony_ci		{
1085e5c31af7Sopenharmony_ci			// Only one vertex
1086e5c31af7Sopenharmony_ci			if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && spec.indexMin == spec.indexMax && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
1087e5c31af7Sopenharmony_ci				continue;
1088e5c31af7Sopenharmony_ci			if (spec.attribs[0].useDefaultAttribute && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
1089e5c31af7Sopenharmony_ci				continue;
1090e5c31af7Sopenharmony_ci
1091e5c31af7Sopenharmony_ci			// Triangle only on one axis
1092e5c31af7Sopenharmony_ci			if (spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLES || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP)
1093e5c31af7Sopenharmony_ci			{
1094e5c31af7Sopenharmony_ci				if (spec.attribs[0].componentCount == 1)
1095e5c31af7Sopenharmony_ci					continue;
1096e5c31af7Sopenharmony_ci				if (spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_FLOAT || spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_INT || spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_UINT)
1097e5c31af7Sopenharmony_ci					continue;
1098e5c31af7Sopenharmony_ci				if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && (spec.indexMax - spec.indexMin) < 2)
1099e5c31af7Sopenharmony_ci					continue;
1100e5c31af7Sopenharmony_ci			}
1101e5c31af7Sopenharmony_ci		}
1102e5c31af7Sopenharmony_ci
1103e5c31af7Sopenharmony_ci		// Add case
1104e5c31af7Sopenharmony_ci		{
1105e5c31af7Sopenharmony_ci			deUint32 hash = spec.hash();
1106e5c31af7Sopenharmony_ci			for (int attrNdx = 0; attrNdx < attributeCount; ++attrNdx)
1107e5c31af7Sopenharmony_ci				hash = (hash << 2) ^ (deUint32)spec.attribs[attrNdx].hash();
1108e5c31af7Sopenharmony_ci
1109e5c31af7Sopenharmony_ci			if (insertedHashes.find(hash) == insertedHashes.end())
1110e5c31af7Sopenharmony_ci			{
1111e5c31af7Sopenharmony_ci				// Only properly aligned and not disallowed cases
1112e5c31af7Sopenharmony_ci				if (spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET			&&
1113e5c31af7Sopenharmony_ci					spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE			&&
1114e5c31af7Sopenharmony_ci					!de::contains(DE_ARRAY_BEGIN(disallowedCases), DE_ARRAY_END(disallowedCases), hash))
1115e5c31af7Sopenharmony_ci				{
1116e5c31af7Sopenharmony_ci					this->addChild(new gls::DrawTest(m_testCtx, m_context.getRenderContext(), spec, de::toString(insertedCount).c_str(), spec.getDesc().c_str()));
1117e5c31af7Sopenharmony_ci				}
1118e5c31af7Sopenharmony_ci				insertedHashes.insert(hash);
1119e5c31af7Sopenharmony_ci
1120e5c31af7Sopenharmony_ci				++insertedCount;
1121e5c31af7Sopenharmony_ci			}
1122e5c31af7Sopenharmony_ci		}
1123e5c31af7Sopenharmony_ci	}
1124e5c31af7Sopenharmony_ci}
1125e5c31af7Sopenharmony_ci
1126e5c31af7Sopenharmony_ci} // anonymous
1127e5c31af7Sopenharmony_ci
1128e5c31af7Sopenharmony_ciDrawTests::DrawTests (Context& context)
1129e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "draw", "Drawing tests")
1130e5c31af7Sopenharmony_ci{
1131e5c31af7Sopenharmony_ci}
1132e5c31af7Sopenharmony_ci
1133e5c31af7Sopenharmony_ciDrawTests::~DrawTests (void)
1134e5c31af7Sopenharmony_ci{
1135e5c31af7Sopenharmony_ci}
1136e5c31af7Sopenharmony_ci
1137e5c31af7Sopenharmony_civoid DrawTests::init (void)
1138e5c31af7Sopenharmony_ci{
1139e5c31af7Sopenharmony_ci	// Basic
1140e5c31af7Sopenharmony_ci	{
1141e5c31af7Sopenharmony_ci		const gls::DrawTestSpec::DrawMethod basicMethods[] =
1142e5c31af7Sopenharmony_ci		{
1143e5c31af7Sopenharmony_ci			gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS,
1144e5c31af7Sopenharmony_ci			gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS,
1145e5c31af7Sopenharmony_ci			gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED,
1146e5c31af7Sopenharmony_ci			gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED,
1147e5c31af7Sopenharmony_ci			gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED,
1148e5c31af7Sopenharmony_ci		};
1149e5c31af7Sopenharmony_ci
1150e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
1151e5c31af7Sopenharmony_ci		{
1152e5c31af7Sopenharmony_ci			const std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
1153e5c31af7Sopenharmony_ci			const std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
1154e5c31af7Sopenharmony_ci
1155e5c31af7Sopenharmony_ci			this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));
1156e5c31af7Sopenharmony_ci		}
1157e5c31af7Sopenharmony_ci	}
1158e5c31af7Sopenharmony_ci
1159e5c31af7Sopenharmony_ci	// extreme instancing
1160e5c31af7Sopenharmony_ci
1161e5c31af7Sopenharmony_ci	this->addChild(new InstancingGroup(m_context, "instancing", "draw tests with a large instance count."));
1162e5c31af7Sopenharmony_ci
1163e5c31af7Sopenharmony_ci	// Random
1164e5c31af7Sopenharmony_ci
1165e5c31af7Sopenharmony_ci	this->addChild(new RandomGroup(m_context, "random", "random draw commands."));
1166e5c31af7Sopenharmony_ci}
1167e5c31af7Sopenharmony_ci
1168e5c31af7Sopenharmony_ci} // Functional
1169e5c31af7Sopenharmony_ci} // gles3
1170e5c31af7Sopenharmony_ci} // deqp
1171