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 Default vertex attribute test
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "es3fDefaultVertexAttributeTests.hpp"
25e5c31af7Sopenharmony_ci#include "tcuVector.hpp"
26e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp"
27e5c31af7Sopenharmony_ci#include "tcuSurface.hpp"
28e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp"
29e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp"
30e5c31af7Sopenharmony_ci#include "gluCallLogWrapper.hpp"
31e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
32e5c31af7Sopenharmony_ci#include "gluObjectWrapper.hpp"
33e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp"
34e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
35e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
36e5c31af7Sopenharmony_ci#include "deMath.h"
37e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
38e5c31af7Sopenharmony_ci#include "deString.h"
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_ci#include <limits>
41e5c31af7Sopenharmony_ci
42e5c31af7Sopenharmony_cinamespace deqp
43e5c31af7Sopenharmony_ci{
44e5c31af7Sopenharmony_cinamespace gles3
45e5c31af7Sopenharmony_ci{
46e5c31af7Sopenharmony_cinamespace Functional
47e5c31af7Sopenharmony_ci{
48e5c31af7Sopenharmony_cinamespace
49e5c31af7Sopenharmony_ci{
50e5c31af7Sopenharmony_ci
51e5c31af7Sopenharmony_cistatic const int s_valueRange = 10;
52e5c31af7Sopenharmony_ci
53e5c31af7Sopenharmony_cistatic const char* const s_passThroughFragmentShaderSource =	"#version 300 es\n"
54e5c31af7Sopenharmony_ci																"layout(location = 0) out mediump vec4 fragColor;\n"
55e5c31af7Sopenharmony_ci																"in mediump vec4 v_color;\n"
56e5c31af7Sopenharmony_ci																"void main (void)\n"
57e5c31af7Sopenharmony_ci																"{\n"
58e5c31af7Sopenharmony_ci																"	fragColor = v_color;\n"
59e5c31af7Sopenharmony_ci																"}\n";
60e5c31af7Sopenharmony_ci
61e5c31af7Sopenharmony_citemplate <typename T1, int S1, typename T2, int S2>
62e5c31af7Sopenharmony_citcu::Vector<T1, S1> convertToTypeVec (const tcu::Vector<T2, S2>& v)
63e5c31af7Sopenharmony_ci{
64e5c31af7Sopenharmony_ci	tcu::Vector<T1, S1> retVal;
65e5c31af7Sopenharmony_ci
66e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < S1; ++ndx)
67e5c31af7Sopenharmony_ci		retVal[ndx] = T1(0);
68e5c31af7Sopenharmony_ci
69e5c31af7Sopenharmony_ci	if (S1 == 4)
70e5c31af7Sopenharmony_ci		retVal[3] = T1(1);
71e5c31af7Sopenharmony_ci
72e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < de::min(S1, S2); ++ndx)
73e5c31af7Sopenharmony_ci		retVal[ndx] = T1(v[ndx]);
74e5c31af7Sopenharmony_ci
75e5c31af7Sopenharmony_ci	return retVal;
76e5c31af7Sopenharmony_ci}
77e5c31af7Sopenharmony_ci
78e5c31af7Sopenharmony_ciclass FloatLoader
79e5c31af7Sopenharmony_ci{
80e5c31af7Sopenharmony_cipublic:
81e5c31af7Sopenharmony_ci	virtual				~FloatLoader	(void) {}
82e5c31af7Sopenharmony_ci
83e5c31af7Sopenharmony_ci	// returns the value loaded
84e5c31af7Sopenharmony_ci	virtual tcu::Vec4	load			(glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const = 0;
85e5c31af7Sopenharmony_ci};
86e5c31af7Sopenharmony_ci
87e5c31af7Sopenharmony_ci#define GEN_DIRECT_FLOAT_LOADER(TYPE, COMPS, TYPECODE, CASENAME, VALUES)				\
88e5c31af7Sopenharmony_ci	class LoaderVertexAttrib##COMPS##TYPECODE : public FloatLoader						\
89e5c31af7Sopenharmony_ci	{																					\
90e5c31af7Sopenharmony_ci	public:																				\
91e5c31af7Sopenharmony_ci		enum																			\
92e5c31af7Sopenharmony_ci		{																				\
93e5c31af7Sopenharmony_ci			NORMALIZING = 0,															\
94e5c31af7Sopenharmony_ci		};																				\
95e5c31af7Sopenharmony_ci		enum																			\
96e5c31af7Sopenharmony_ci		{																				\
97e5c31af7Sopenharmony_ci			COMPONENTS = (COMPS)														\
98e5c31af7Sopenharmony_ci		};																				\
99e5c31af7Sopenharmony_ci		typedef TYPE Type;																\
100e5c31af7Sopenharmony_ci																						\
101e5c31af7Sopenharmony_ci		tcu::Vec4 load (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const	\
102e5c31af7Sopenharmony_ci		{																				\
103e5c31af7Sopenharmony_ci			tcu::Vector<TYPE, COMPONENTS> value;										\
104e5c31af7Sopenharmony_ci			value = convertToTypeVec<Type, COMPONENTS>(v);								\
105e5c31af7Sopenharmony_ci																						\
106e5c31af7Sopenharmony_ci			gl.glVertexAttrib ##COMPS ##TYPECODE VALUES;								\
107e5c31af7Sopenharmony_ci			return convertToTypeVec<float, 4>(value);									\
108e5c31af7Sopenharmony_ci		}																				\
109e5c31af7Sopenharmony_ci																						\
110e5c31af7Sopenharmony_ci		static const char* getCaseName (void)											\
111e5c31af7Sopenharmony_ci		{																				\
112e5c31af7Sopenharmony_ci			return CASENAME;															\
113e5c31af7Sopenharmony_ci		}																				\
114e5c31af7Sopenharmony_ci																						\
115e5c31af7Sopenharmony_ci		static const char* getName (void)												\
116e5c31af7Sopenharmony_ci		{																				\
117e5c31af7Sopenharmony_ci			return "VertexAttrib" #COMPS #TYPECODE;										\
118e5c31af7Sopenharmony_ci		}																				\
119e5c31af7Sopenharmony_ci	}
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_ci#define GEN_INDIRECT_FLOAT_LOADER(TYPE, COMPS, TYPECODE, CASENAME)						\
122e5c31af7Sopenharmony_ci	class LoaderVertexAttrib##COMPS##TYPECODE : public FloatLoader						\
123e5c31af7Sopenharmony_ci	{																					\
124e5c31af7Sopenharmony_ci	public:																				\
125e5c31af7Sopenharmony_ci		enum																			\
126e5c31af7Sopenharmony_ci		{																				\
127e5c31af7Sopenharmony_ci			NORMALIZING = 0,															\
128e5c31af7Sopenharmony_ci		};																				\
129e5c31af7Sopenharmony_ci		enum																			\
130e5c31af7Sopenharmony_ci		{																				\
131e5c31af7Sopenharmony_ci			COMPONENTS = (COMPS)														\
132e5c31af7Sopenharmony_ci		};																				\
133e5c31af7Sopenharmony_ci		typedef TYPE Type;																\
134e5c31af7Sopenharmony_ci																						\
135e5c31af7Sopenharmony_ci		tcu::Vec4 load (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const	\
136e5c31af7Sopenharmony_ci		{																				\
137e5c31af7Sopenharmony_ci			tcu::Vector<TYPE, COMPONENTS> value;										\
138e5c31af7Sopenharmony_ci			value = convertToTypeVec<Type, COMPONENTS>(v);								\
139e5c31af7Sopenharmony_ci																						\
140e5c31af7Sopenharmony_ci			gl.glVertexAttrib ##COMPS ##TYPECODE (index, value.getPtr());				\
141e5c31af7Sopenharmony_ci			return convertToTypeVec<float, 4>(value);									\
142e5c31af7Sopenharmony_ci		}																				\
143e5c31af7Sopenharmony_ci																						\
144e5c31af7Sopenharmony_ci		static const char* getCaseName (void)											\
145e5c31af7Sopenharmony_ci		{																				\
146e5c31af7Sopenharmony_ci			return CASENAME;															\
147e5c31af7Sopenharmony_ci		}																				\
148e5c31af7Sopenharmony_ci																						\
149e5c31af7Sopenharmony_ci		static const char* getName (void)												\
150e5c31af7Sopenharmony_ci		{																				\
151e5c31af7Sopenharmony_ci			return "VertexAttrib" #COMPS #TYPECODE;										\
152e5c31af7Sopenharmony_ci		}																				\
153e5c31af7Sopenharmony_ci	}
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_ci#define GEN_DIRECT_INTEGER_LOADER(TYPE, COMPS, TYPECODE, CASENAME, VALUES)				\
156e5c31af7Sopenharmony_ci	class LoaderVertexAttribI##COMPS##TYPECODE : public FloatLoader						\
157e5c31af7Sopenharmony_ci	{																					\
158e5c31af7Sopenharmony_ci	public:																				\
159e5c31af7Sopenharmony_ci		enum																			\
160e5c31af7Sopenharmony_ci		{																				\
161e5c31af7Sopenharmony_ci			NORMALIZING = 0,															\
162e5c31af7Sopenharmony_ci		};																				\
163e5c31af7Sopenharmony_ci		enum																			\
164e5c31af7Sopenharmony_ci		{																				\
165e5c31af7Sopenharmony_ci			COMPONENTS = (COMPS)														\
166e5c31af7Sopenharmony_ci		};																				\
167e5c31af7Sopenharmony_ci		typedef TYPE Type;																\
168e5c31af7Sopenharmony_ci																						\
169e5c31af7Sopenharmony_ci		tcu::Vec4 load (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const	\
170e5c31af7Sopenharmony_ci		{																				\
171e5c31af7Sopenharmony_ci			tcu::Vector<TYPE, COMPONENTS> value;										\
172e5c31af7Sopenharmony_ci			value = convertToTypeVec<Type, COMPONENTS>(v);								\
173e5c31af7Sopenharmony_ci																						\
174e5c31af7Sopenharmony_ci			gl.glVertexAttribI ##COMPS ##TYPECODE VALUES;								\
175e5c31af7Sopenharmony_ci			return convertToTypeVec<float, 4>(value);									\
176e5c31af7Sopenharmony_ci		}																				\
177e5c31af7Sopenharmony_ci																						\
178e5c31af7Sopenharmony_ci		static const char* getCaseName (void)											\
179e5c31af7Sopenharmony_ci		{																				\
180e5c31af7Sopenharmony_ci			return CASENAME;															\
181e5c31af7Sopenharmony_ci		}																				\
182e5c31af7Sopenharmony_ci																						\
183e5c31af7Sopenharmony_ci		static const char* getName (void)												\
184e5c31af7Sopenharmony_ci		{																				\
185e5c31af7Sopenharmony_ci			return "VertexAttrib" #COMPS #TYPECODE;										\
186e5c31af7Sopenharmony_ci		}																				\
187e5c31af7Sopenharmony_ci	}
188e5c31af7Sopenharmony_ci
189e5c31af7Sopenharmony_ci#define GEN_INDIRECT_INTEGER_LOADER(TYPE, COMPS, TYPECODE, CASENAME)					\
190e5c31af7Sopenharmony_ci	class LoaderVertexAttribI##COMPS##TYPECODE : public FloatLoader						\
191e5c31af7Sopenharmony_ci	{																					\
192e5c31af7Sopenharmony_ci	public:																				\
193e5c31af7Sopenharmony_ci		enum																			\
194e5c31af7Sopenharmony_ci		{																				\
195e5c31af7Sopenharmony_ci			NORMALIZING = 0,															\
196e5c31af7Sopenharmony_ci		};																				\
197e5c31af7Sopenharmony_ci		enum																			\
198e5c31af7Sopenharmony_ci		{																				\
199e5c31af7Sopenharmony_ci			COMPONENTS = (COMPS)														\
200e5c31af7Sopenharmony_ci		};																				\
201e5c31af7Sopenharmony_ci		typedef TYPE Type;																\
202e5c31af7Sopenharmony_ci																						\
203e5c31af7Sopenharmony_ci		tcu::Vec4 load (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const	\
204e5c31af7Sopenharmony_ci		{																				\
205e5c31af7Sopenharmony_ci			tcu::Vector<TYPE, COMPONENTS> value;										\
206e5c31af7Sopenharmony_ci			value = convertToTypeVec<Type, COMPONENTS>(v);								\
207e5c31af7Sopenharmony_ci																						\
208e5c31af7Sopenharmony_ci			gl.glVertexAttribI ##COMPS ##TYPECODE (index, value.getPtr());				\
209e5c31af7Sopenharmony_ci			return convertToTypeVec<float, 4>(value);									\
210e5c31af7Sopenharmony_ci		}																				\
211e5c31af7Sopenharmony_ci																						\
212e5c31af7Sopenharmony_ci		static const char* getCaseName (void)											\
213e5c31af7Sopenharmony_ci		{																				\
214e5c31af7Sopenharmony_ci			return CASENAME;															\
215e5c31af7Sopenharmony_ci		}																				\
216e5c31af7Sopenharmony_ci																						\
217e5c31af7Sopenharmony_ci		static const char* getName (void)												\
218e5c31af7Sopenharmony_ci		{																				\
219e5c31af7Sopenharmony_ci			return "VertexAttrib" #COMPS #TYPECODE;										\
220e5c31af7Sopenharmony_ci		}																				\
221e5c31af7Sopenharmony_ci	}
222e5c31af7Sopenharmony_ci
223e5c31af7Sopenharmony_ciGEN_DIRECT_FLOAT_LOADER(float, 1, f, "vertex_attrib_1f", (index, value.x()));
224e5c31af7Sopenharmony_ciGEN_DIRECT_FLOAT_LOADER(float, 2, f, "vertex_attrib_2f", (index, value.x(), value.y()));
225e5c31af7Sopenharmony_ciGEN_DIRECT_FLOAT_LOADER(float, 3, f, "vertex_attrib_3f", (index, value.x(), value.y(), value.z()));
226e5c31af7Sopenharmony_ciGEN_DIRECT_FLOAT_LOADER(float, 4, f, "vertex_attrib_4f", (index, value.x(), value.y(), value.z(), value.w()));
227e5c31af7Sopenharmony_ci
228e5c31af7Sopenharmony_ciGEN_INDIRECT_FLOAT_LOADER(float, 1, fv, "vertex_attrib_1fv");
229e5c31af7Sopenharmony_ciGEN_INDIRECT_FLOAT_LOADER(float, 2, fv, "vertex_attrib_2fv");
230e5c31af7Sopenharmony_ciGEN_INDIRECT_FLOAT_LOADER(float, 3, fv, "vertex_attrib_3fv");
231e5c31af7Sopenharmony_ciGEN_INDIRECT_FLOAT_LOADER(float, 4, fv, "vertex_attrib_4fv");
232e5c31af7Sopenharmony_ci
233e5c31af7Sopenharmony_ciGEN_DIRECT_INTEGER_LOADER(deInt32, 4, i, "vertex_attribi_4i", (index, value.x(), value.y(), value.z(), value.w()));
234e5c31af7Sopenharmony_ciGEN_INDIRECT_INTEGER_LOADER(deInt32, 4, iv, "vertex_attribi_4iv");
235e5c31af7Sopenharmony_ci
236e5c31af7Sopenharmony_ciGEN_DIRECT_INTEGER_LOADER(deUint32, 4, ui, "vertex_attribi_4ui", (index, value.x(), value.y(), value.z(), value.w()));
237e5c31af7Sopenharmony_ciGEN_INDIRECT_INTEGER_LOADER(deUint32, 4, uiv, "vertex_attribi_4uiv");
238e5c31af7Sopenharmony_ci
239e5c31af7Sopenharmony_ciclass AttributeCase : public TestCase
240e5c31af7Sopenharmony_ci{
241e5c31af7Sopenharmony_ci									AttributeCase			(Context& ctx, const char* name, const char* desc, const char* funcName, bool normalizing, bool useNegative, glu::DataType dataType);
242e5c31af7Sopenharmony_cipublic:
243e5c31af7Sopenharmony_ci	template<typename LoaderType>
244e5c31af7Sopenharmony_ci	static AttributeCase*			create					(Context& ctx, glu::DataType dataType);
245e5c31af7Sopenharmony_ci									~AttributeCase			(void);
246e5c31af7Sopenharmony_ci
247e5c31af7Sopenharmony_ciprivate:
248e5c31af7Sopenharmony_ci	void							init					(void);
249e5c31af7Sopenharmony_ci	void							deinit					(void);
250e5c31af7Sopenharmony_ci	IterateResult					iterate					(void);
251e5c31af7Sopenharmony_ci
252e5c31af7Sopenharmony_ci	glu::DataType					getTargetType			(void) const;
253e5c31af7Sopenharmony_ci	std::string						genVertexSource			(void) const;
254e5c31af7Sopenharmony_ci	bool							renderWithValue			(const tcu::Vec4& v);
255e5c31af7Sopenharmony_ci	tcu::Vec4						computeColor			(const tcu::Vec4& value);
256e5c31af7Sopenharmony_ci	bool							verifyUnicoloredBuffer	(const tcu::Surface& scene, const tcu::Vec4& refValue);
257e5c31af7Sopenharmony_ci
258e5c31af7Sopenharmony_ci	const bool						m_normalizing;
259e5c31af7Sopenharmony_ci	const bool						m_useNegativeValues;
260e5c31af7Sopenharmony_ci	const char* const				m_funcName;
261e5c31af7Sopenharmony_ci	const glu::DataType				m_dataType;
262e5c31af7Sopenharmony_ci	const FloatLoader*				m_loader;
263e5c31af7Sopenharmony_ci	glu::ShaderProgram*				m_program;
264e5c31af7Sopenharmony_ci	deUint32						m_bufID;
265e5c31af7Sopenharmony_ci	bool							m_allIterationsPassed;
266e5c31af7Sopenharmony_ci	int								m_iteration;
267e5c31af7Sopenharmony_ci
268e5c31af7Sopenharmony_ci	enum
269e5c31af7Sopenharmony_ci	{
270e5c31af7Sopenharmony_ci		RENDER_SIZE = 32
271e5c31af7Sopenharmony_ci	};
272e5c31af7Sopenharmony_ci};
273e5c31af7Sopenharmony_ci
274e5c31af7Sopenharmony_ciAttributeCase::AttributeCase (Context& ctx, const char* name, const char* desc, const char* funcName, bool normalizing, bool useNegative, glu::DataType dataType)
275e5c31af7Sopenharmony_ci	: TestCase				(ctx, name, desc)
276e5c31af7Sopenharmony_ci	, m_normalizing			(normalizing)
277e5c31af7Sopenharmony_ci	, m_useNegativeValues	(useNegative)
278e5c31af7Sopenharmony_ci	, m_funcName			(funcName)
279e5c31af7Sopenharmony_ci	, m_dataType			(dataType)
280e5c31af7Sopenharmony_ci	, m_loader				(DE_NULL)
281e5c31af7Sopenharmony_ci	, m_program				(DE_NULL)
282e5c31af7Sopenharmony_ci	, m_bufID				(0)
283e5c31af7Sopenharmony_ci	, m_allIterationsPassed	(true)
284e5c31af7Sopenharmony_ci	, m_iteration			(0)
285e5c31af7Sopenharmony_ci{
286e5c31af7Sopenharmony_ci}
287e5c31af7Sopenharmony_ci
288e5c31af7Sopenharmony_citemplate<typename LoaderType>
289e5c31af7Sopenharmony_ciAttributeCase* AttributeCase::create (Context& ctx, glu::DataType dataType)
290e5c31af7Sopenharmony_ci{
291e5c31af7Sopenharmony_ci	AttributeCase* retVal = new AttributeCase(ctx,
292e5c31af7Sopenharmony_ci											  LoaderType::getCaseName(),
293e5c31af7Sopenharmony_ci											  (std::string("Test ") + LoaderType::getName()).c_str(),
294e5c31af7Sopenharmony_ci											  LoaderType::getName(),
295e5c31af7Sopenharmony_ci											  LoaderType::NORMALIZING != 0,
296e5c31af7Sopenharmony_ci											  std::numeric_limits<typename LoaderType::Type>::is_signed,
297e5c31af7Sopenharmony_ci											  dataType);
298e5c31af7Sopenharmony_ci	retVal->m_loader = new LoaderType();
299e5c31af7Sopenharmony_ci	return retVal;
300e5c31af7Sopenharmony_ci}
301e5c31af7Sopenharmony_ci
302e5c31af7Sopenharmony_ciAttributeCase::~AttributeCase (void)
303e5c31af7Sopenharmony_ci{
304e5c31af7Sopenharmony_ci	deinit();
305e5c31af7Sopenharmony_ci}
306e5c31af7Sopenharmony_ci
307e5c31af7Sopenharmony_civoid AttributeCase::init (void)
308e5c31af7Sopenharmony_ci{
309e5c31af7Sopenharmony_ci	if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || m_context.getRenderTarget().getHeight() < RENDER_SIZE)
310e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Render target must be at least " + de::toString<int>(RENDER_SIZE) + "x" + de::toString<int>(RENDER_SIZE));
311e5c31af7Sopenharmony_ci
312e5c31af7Sopenharmony_ci	// log test info
313e5c31af7Sopenharmony_ci
314e5c31af7Sopenharmony_ci	{
315e5c31af7Sopenharmony_ci		const float			maxRange		= (m_normalizing) ? (1.0f) : (s_valueRange);
316e5c31af7Sopenharmony_ci		const float			minRange		= (m_useNegativeValues) ? (-maxRange) : (0.0f);
317e5c31af7Sopenharmony_ci
318e5c31af7Sopenharmony_ci		m_testCtx.getLog()
319e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message
320e5c31af7Sopenharmony_ci			<< "Loading attribute values using " << m_funcName << "\n"
321e5c31af7Sopenharmony_ci			<< "Attribute type: " << glu::getDataTypeName(m_dataType) << "\n"
322e5c31af7Sopenharmony_ci			<< "Attribute value range: [" << minRange << ", " << maxRange << "]"
323e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
324e5c31af7Sopenharmony_ci	}
325e5c31af7Sopenharmony_ci
326e5c31af7Sopenharmony_ci	// gen shader and base quad
327e5c31af7Sopenharmony_ci
328e5c31af7Sopenharmony_ci	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource()) << glu::FragmentSource(s_passThroughFragmentShaderSource));
329e5c31af7Sopenharmony_ci	m_testCtx.getLog() << *m_program;
330e5c31af7Sopenharmony_ci	if (!m_program->isOk())
331e5c31af7Sopenharmony_ci		throw tcu::TestError("could not build program");
332e5c31af7Sopenharmony_ci
333e5c31af7Sopenharmony_ci	{
334e5c31af7Sopenharmony_ci		const tcu::Vec4 fullscreenQuad[] =
335e5c31af7Sopenharmony_ci		{
336e5c31af7Sopenharmony_ci			tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
337e5c31af7Sopenharmony_ci			tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
338e5c31af7Sopenharmony_ci			tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
339e5c31af7Sopenharmony_ci			tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
340e5c31af7Sopenharmony_ci		};
341e5c31af7Sopenharmony_ci
342e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
343e5c31af7Sopenharmony_ci
344e5c31af7Sopenharmony_ci		gl.genBuffers(1, &m_bufID);
345e5c31af7Sopenharmony_ci		gl.bindBuffer(GL_ARRAY_BUFFER, m_bufID);
346e5c31af7Sopenharmony_ci		gl.bufferData(GL_ARRAY_BUFFER, sizeof(fullscreenQuad), fullscreenQuad, GL_STATIC_DRAW);
347e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "fill buffer");
348e5c31af7Sopenharmony_ci	}
349e5c31af7Sopenharmony_ci}
350e5c31af7Sopenharmony_ci
351e5c31af7Sopenharmony_civoid AttributeCase::deinit (void)
352e5c31af7Sopenharmony_ci{
353e5c31af7Sopenharmony_ci	delete m_loader;
354e5c31af7Sopenharmony_ci	m_loader = DE_NULL;
355e5c31af7Sopenharmony_ci
356e5c31af7Sopenharmony_ci	delete m_program;
357e5c31af7Sopenharmony_ci	m_program = DE_NULL;
358e5c31af7Sopenharmony_ci
359e5c31af7Sopenharmony_ci	if (m_bufID)
360e5c31af7Sopenharmony_ci	{
361e5c31af7Sopenharmony_ci		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_bufID);
362e5c31af7Sopenharmony_ci		m_bufID = 0;
363e5c31af7Sopenharmony_ci	}
364e5c31af7Sopenharmony_ci}
365e5c31af7Sopenharmony_ci
366e5c31af7Sopenharmony_ciAttributeCase::IterateResult AttributeCase::iterate (void)
367e5c31af7Sopenharmony_ci{
368e5c31af7Sopenharmony_ci	static const tcu::Vec4 testValues[] =
369e5c31af7Sopenharmony_ci	{
370e5c31af7Sopenharmony_ci		tcu::Vec4(0.0f, 0.5f, 0.2f, 1.0f),
371e5c31af7Sopenharmony_ci		tcu::Vec4(0.1f, 0.7f, 1.0f, 0.6f),
372e5c31af7Sopenharmony_ci		tcu::Vec4(0.4f, 0.2f, 0.0f, 0.5f),
373e5c31af7Sopenharmony_ci		tcu::Vec4(0.5f, 0.0f, 0.9f, 0.1f),
374e5c31af7Sopenharmony_ci		tcu::Vec4(0.6f, 0.2f, 0.2f, 0.9f),
375e5c31af7Sopenharmony_ci		tcu::Vec4(0.9f, 1.0f, 0.0f, 0.0f),
376e5c31af7Sopenharmony_ci		tcu::Vec4(1.0f, 0.5f, 0.3f, 0.8f),
377e5c31af7Sopenharmony_ci	};
378e5c31af7Sopenharmony_ci
379e5c31af7Sopenharmony_ci	const tcu::ScopedLogSection section(m_testCtx.getLog(), "Iteration", "Iteration " + de::toString(m_iteration+1) + "/" + de::toString(DE_LENGTH_OF_ARRAY(testValues)));
380e5c31af7Sopenharmony_ci
381e5c31af7Sopenharmony_ci	// Test normalizing transfers with whole range, non-normalizing with up to s_valueRange
382e5c31af7Sopenharmony_ci	const tcu::Vec4 testValue = ((m_useNegativeValues) ? (testValues[m_iteration] * 2.0f - tcu::Vec4(1.0f)) : (testValues[m_iteration])) * ((m_normalizing) ? (1.0f) : ((float)s_valueRange));
383e5c31af7Sopenharmony_ci
384e5c31af7Sopenharmony_ci	if (!renderWithValue(testValue))
385e5c31af7Sopenharmony_ci		m_allIterationsPassed = false;
386e5c31af7Sopenharmony_ci
387e5c31af7Sopenharmony_ci	// continue
388e5c31af7Sopenharmony_ci
389e5c31af7Sopenharmony_ci	if (++m_iteration < DE_LENGTH_OF_ARRAY(testValues))
390e5c31af7Sopenharmony_ci		return CONTINUE;
391e5c31af7Sopenharmony_ci
392e5c31af7Sopenharmony_ci	if (m_allIterationsPassed)
393e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
394e5c31af7Sopenharmony_ci	else
395e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected values");
396e5c31af7Sopenharmony_ci
397e5c31af7Sopenharmony_ci	return STOP;
398e5c31af7Sopenharmony_ci}
399e5c31af7Sopenharmony_ci
400e5c31af7Sopenharmony_cistd::string AttributeCase::genVertexSource (void) const
401e5c31af7Sopenharmony_ci{
402e5c31af7Sopenharmony_ci	const int			vectorSize	= (glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeMatrixNumRows(m_dataType)) : (glu::isDataTypeVector(m_dataType)) ? (glu::getDataTypeScalarSize(m_dataType)) : (-1);
403e5c31af7Sopenharmony_ci	const char* const	vectorType	= glu::getDataTypeName((glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeVector(glu::TYPE_FLOAT, vectorSize)) : (glu::isDataTypeVector(m_dataType)) ? (glu::getDataTypeVector(glu::TYPE_FLOAT, vectorSize)) : (glu::TYPE_FLOAT));
404e5c31af7Sopenharmony_ci	const int			components	= (glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeMatrixNumRows(m_dataType)) : (glu::getDataTypeScalarSize(m_dataType));
405e5c31af7Sopenharmony_ci	std::ostringstream	buf;
406e5c31af7Sopenharmony_ci
407e5c31af7Sopenharmony_ci	buf <<	"#version 300 es\n"
408e5c31af7Sopenharmony_ci			"in highp vec4 a_position;\n"
409e5c31af7Sopenharmony_ci			"in highp " << glu::getDataTypeName(m_dataType) << " a_value;\n"
410e5c31af7Sopenharmony_ci			"out highp vec4 v_color;\n"
411e5c31af7Sopenharmony_ci			"void main (void)\n"
412e5c31af7Sopenharmony_ci			"{\n"
413e5c31af7Sopenharmony_ci			"	gl_Position = a_position;\n"
414e5c31af7Sopenharmony_ci			"\n";
415e5c31af7Sopenharmony_ci
416e5c31af7Sopenharmony_ci	if (m_normalizing)
417e5c31af7Sopenharmony_ci		buf << "	highp " << vectorType << " normalizedValue = " << ((glu::getDataTypeScalarType(m_dataType) == glu::TYPE_FLOAT) ? ("") : (vectorType)) << "(a_value" << ((glu::isDataTypeMatrix(m_dataType)) ? ("[1]") : ("")) << ");\n";
418e5c31af7Sopenharmony_ci	else
419e5c31af7Sopenharmony_ci		buf << "	highp " << vectorType << " normalizedValue = " << ((glu::getDataTypeScalarType(m_dataType) == glu::TYPE_FLOAT) ? ("") : (vectorType)) << "(a_value" << ((glu::isDataTypeMatrix(m_dataType)) ? ("[1]") : ("")) << ") / float(" << s_valueRange << ");\n";
420e5c31af7Sopenharmony_ci
421e5c31af7Sopenharmony_ci	if (m_useNegativeValues)
422e5c31af7Sopenharmony_ci		buf << "	highp " << vectorType << " positiveNormalizedValue = (normalizedValue + " << vectorType << "(1.0)) / 2.0;\n";
423e5c31af7Sopenharmony_ci	else
424e5c31af7Sopenharmony_ci		buf << "	highp " << vectorType << " positiveNormalizedValue = normalizedValue;\n";
425e5c31af7Sopenharmony_ci
426e5c31af7Sopenharmony_ci	if (components == 1)
427e5c31af7Sopenharmony_ci		buf << "	v_color = vec4(positiveNormalizedValue, 0.0, 0.0, 1.0);\n";
428e5c31af7Sopenharmony_ci	else if (components == 2)
429e5c31af7Sopenharmony_ci		buf << "	v_color = vec4(positiveNormalizedValue.xy, 0.0, 1.0);\n";
430e5c31af7Sopenharmony_ci	else if (components == 3)
431e5c31af7Sopenharmony_ci		buf << "	v_color = vec4(positiveNormalizedValue.xyz, 1.0);\n";
432e5c31af7Sopenharmony_ci	else if (components == 4)
433e5c31af7Sopenharmony_ci		buf << "	v_color = vec4((positiveNormalizedValue.xy + positiveNormalizedValue.zz) / 2.0, positiveNormalizedValue.w, 1.0);\n";
434e5c31af7Sopenharmony_ci	else
435e5c31af7Sopenharmony_ci		DE_ASSERT(DE_FALSE);
436e5c31af7Sopenharmony_ci
437e5c31af7Sopenharmony_ci	buf << "}\n";
438e5c31af7Sopenharmony_ci
439e5c31af7Sopenharmony_ci	return buf.str();
440e5c31af7Sopenharmony_ci}
441e5c31af7Sopenharmony_ci
442e5c31af7Sopenharmony_cibool AttributeCase::renderWithValue (const tcu::Vec4& v)
443e5c31af7Sopenharmony_ci{
444e5c31af7Sopenharmony_ci	glu::CallLogWrapper	gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
445e5c31af7Sopenharmony_ci
446e5c31af7Sopenharmony_ci	gl.enableLogging(true);
447e5c31af7Sopenharmony_ci
448e5c31af7Sopenharmony_ci	const int			positionIndex	= gl.glGetAttribLocation(m_program->getProgram(), "a_position");
449e5c31af7Sopenharmony_ci	const int			valueIndex		= gl.glGetAttribLocation(m_program->getProgram(), "a_value");
450e5c31af7Sopenharmony_ci	tcu::Surface		dest			(RENDER_SIZE, RENDER_SIZE);
451e5c31af7Sopenharmony_ci	tcu::Vec4			loadedValue;
452e5c31af7Sopenharmony_ci
453e5c31af7Sopenharmony_ci	gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
454e5c31af7Sopenharmony_ci	gl.glClear(GL_COLOR_BUFFER_BIT);
455e5c31af7Sopenharmony_ci	gl.glViewport(0, 0, RENDER_SIZE, RENDER_SIZE);
456e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup");
457e5c31af7Sopenharmony_ci
458e5c31af7Sopenharmony_ci	gl.glBindBuffer(GL_ARRAY_BUFFER, m_bufID);
459e5c31af7Sopenharmony_ci	gl.glVertexAttribPointer(positionIndex, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
460e5c31af7Sopenharmony_ci	gl.glEnableVertexAttribArray(positionIndex);
461e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.glGetError(), "position va");
462e5c31af7Sopenharmony_ci
463e5c31af7Sopenharmony_ci	// transfer test value. Load to the second column in the matrix case
464e5c31af7Sopenharmony_ci	loadedValue = m_loader->load(gl, (glu::isDataTypeMatrix(m_dataType)) ? (valueIndex + 1) : (valueIndex), v);
465e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.glGetError(), "default va");
466e5c31af7Sopenharmony_ci
467e5c31af7Sopenharmony_ci	gl.glUseProgram(m_program->getProgram());
468e5c31af7Sopenharmony_ci	gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
469e5c31af7Sopenharmony_ci	gl.glUseProgram(0);
470e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.glGetError(), "draw");
471e5c31af7Sopenharmony_ci
472e5c31af7Sopenharmony_ci	glu::readPixels(m_context.getRenderContext(), 0, 0, dest.getAccess());
473e5c31af7Sopenharmony_ci
474e5c31af7Sopenharmony_ci	// check whole result is colored correctly
475e5c31af7Sopenharmony_ci	return verifyUnicoloredBuffer(dest, computeColor(loadedValue));
476e5c31af7Sopenharmony_ci}
477e5c31af7Sopenharmony_ci
478e5c31af7Sopenharmony_citcu::Vec4 AttributeCase::computeColor (const tcu::Vec4& value)
479e5c31af7Sopenharmony_ci{
480e5c31af7Sopenharmony_ci	const tcu::Vec4 normalizedValue			= value / ((m_normalizing) ? (1.0f) : ((float)s_valueRange));
481e5c31af7Sopenharmony_ci	const tcu::Vec4 positiveNormalizedValue = ((m_useNegativeValues) ? ((normalizedValue + tcu::Vec4(1.0f)) / 2.0f) : (normalizedValue));
482e5c31af7Sopenharmony_ci	const int		components				= (glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeMatrixNumRows(m_dataType)) : (glu::getDataTypeScalarSize(m_dataType));
483e5c31af7Sopenharmony_ci
484e5c31af7Sopenharmony_ci	if (components == 1)
485e5c31af7Sopenharmony_ci		return tcu::Vec4(positiveNormalizedValue.x(), 0.0f, 0.0f, 1.0f);
486e5c31af7Sopenharmony_ci	else if (components == 2)
487e5c31af7Sopenharmony_ci		return tcu::Vec4(positiveNormalizedValue.x(), positiveNormalizedValue.y(), 0.0f, 1.0f);
488e5c31af7Sopenharmony_ci	else if (components == 3)
489e5c31af7Sopenharmony_ci		return tcu::Vec4(positiveNormalizedValue.x(), positiveNormalizedValue.y(), positiveNormalizedValue.z(), 1.0f);
490e5c31af7Sopenharmony_ci	else if (components == 4)
491e5c31af7Sopenharmony_ci		return tcu::Vec4((positiveNormalizedValue.x() + positiveNormalizedValue.z()) / 2.0f, (positiveNormalizedValue.y() + positiveNormalizedValue.z()) / 2.0f, positiveNormalizedValue.w(), 1.0f);
492e5c31af7Sopenharmony_ci	else
493e5c31af7Sopenharmony_ci		DE_ASSERT(DE_FALSE);
494e5c31af7Sopenharmony_ci
495e5c31af7Sopenharmony_ci	return tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
496e5c31af7Sopenharmony_ci}
497e5c31af7Sopenharmony_ci
498e5c31af7Sopenharmony_cibool AttributeCase::verifyUnicoloredBuffer (const tcu::Surface& scene, const tcu::Vec4& refValue)
499e5c31af7Sopenharmony_ci{
500e5c31af7Sopenharmony_ci	tcu::Surface	errorMask		(RENDER_SIZE, RENDER_SIZE);
501e5c31af7Sopenharmony_ci	const tcu::RGBA	refColor		(refValue);
502e5c31af7Sopenharmony_ci	const int		resultThreshold	= 2;
503e5c31af7Sopenharmony_ci	const tcu::RGBA	colorThreshold	= m_context.getRenderTarget().getPixelFormat().getColorThreshold() * resultThreshold;
504e5c31af7Sopenharmony_ci	bool			error			= false;
505e5c31af7Sopenharmony_ci
506e5c31af7Sopenharmony_ci	tcu::RGBA		exampleColor;
507e5c31af7Sopenharmony_ci	tcu::IVec2		examplePos;
508e5c31af7Sopenharmony_ci
509e5c31af7Sopenharmony_ci	tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toIVec());
510e5c31af7Sopenharmony_ci
511e5c31af7Sopenharmony_ci	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying rendered image. Expecting color " << refColor << ", threshold " << colorThreshold << tcu::TestLog::EndMessage;
512e5c31af7Sopenharmony_ci
513e5c31af7Sopenharmony_ci	for (int y = 0; y < RENDER_SIZE; ++y)
514e5c31af7Sopenharmony_ci	for (int x = 0; x < RENDER_SIZE; ++x)
515e5c31af7Sopenharmony_ci	{
516e5c31af7Sopenharmony_ci		const tcu::RGBA color = scene.getPixel(x, y);
517e5c31af7Sopenharmony_ci
518e5c31af7Sopenharmony_ci		if (de::abs(color.getRed()   - refColor.getRed())   > colorThreshold.getRed()   ||
519e5c31af7Sopenharmony_ci			de::abs(color.getGreen() - refColor.getGreen()) > colorThreshold.getGreen() ||
520e5c31af7Sopenharmony_ci			de::abs(color.getBlue()  - refColor.getBlue())  > colorThreshold.getBlue())
521e5c31af7Sopenharmony_ci		{
522e5c31af7Sopenharmony_ci			// first error
523e5c31af7Sopenharmony_ci			if (!error)
524e5c31af7Sopenharmony_ci			{
525e5c31af7Sopenharmony_ci				exampleColor = color;
526e5c31af7Sopenharmony_ci				examplePos = tcu::IVec2(x, y);
527e5c31af7Sopenharmony_ci			}
528e5c31af7Sopenharmony_ci
529e5c31af7Sopenharmony_ci			error = true;
530e5c31af7Sopenharmony_ci			errorMask.setPixel(x, y, tcu::RGBA::red());
531e5c31af7Sopenharmony_ci		}
532e5c31af7Sopenharmony_ci	}
533e5c31af7Sopenharmony_ci
534e5c31af7Sopenharmony_ci	if (!error)
535e5c31af7Sopenharmony_ci		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered image is valid." << tcu::TestLog::EndMessage;
536e5c31af7Sopenharmony_ci	else
537e5c31af7Sopenharmony_ci	{
538e5c31af7Sopenharmony_ci		m_testCtx.getLog()	<< tcu::TestLog::Message
539e5c31af7Sopenharmony_ci							<< "Found invalid pixel(s).\n"
540e5c31af7Sopenharmony_ci							<< "Pixel at (" << examplePos.x() << ", " << examplePos.y() << ") color: " << exampleColor
541e5c31af7Sopenharmony_ci							<< tcu::TestLog::EndMessage
542e5c31af7Sopenharmony_ci							<< tcu::TestLog::ImageSet("Result", "Render result")
543e5c31af7Sopenharmony_ci							<< tcu::TestLog::Image("Result", "Result", scene)
544e5c31af7Sopenharmony_ci							<< tcu::TestLog::Image("ErrorMask", "Error Mask", errorMask)
545e5c31af7Sopenharmony_ci							<< tcu::TestLog::EndImageSet;
546e5c31af7Sopenharmony_ci	}
547e5c31af7Sopenharmony_ci
548e5c31af7Sopenharmony_ci	return !error;
549e5c31af7Sopenharmony_ci}
550e5c31af7Sopenharmony_ci
551e5c31af7Sopenharmony_ci} // anonymous
552e5c31af7Sopenharmony_ci
553e5c31af7Sopenharmony_ciDefaultVertexAttributeTests::DefaultVertexAttributeTests (Context& context)
554e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "default_vertex_attrib", "Test default vertex attributes")
555e5c31af7Sopenharmony_ci{
556e5c31af7Sopenharmony_ci}
557e5c31af7Sopenharmony_ci
558e5c31af7Sopenharmony_ciDefaultVertexAttributeTests::~DefaultVertexAttributeTests (void)
559e5c31af7Sopenharmony_ci{
560e5c31af7Sopenharmony_ci}
561e5c31af7Sopenharmony_ci
562e5c31af7Sopenharmony_civoid DefaultVertexAttributeTests::init (void)
563e5c31af7Sopenharmony_ci{
564e5c31af7Sopenharmony_ci	struct Target
565e5c31af7Sopenharmony_ci	{
566e5c31af7Sopenharmony_ci		const char*		name;
567e5c31af7Sopenharmony_ci		glu::DataType	dataType;
568e5c31af7Sopenharmony_ci		bool			reducedTestSets;	// !< use reduced coverage
569e5c31af7Sopenharmony_ci	};
570e5c31af7Sopenharmony_ci
571e5c31af7Sopenharmony_ci	static const Target floatTargets[] =
572e5c31af7Sopenharmony_ci	{
573e5c31af7Sopenharmony_ci		{ "float",	glu::TYPE_FLOAT,		false	},
574e5c31af7Sopenharmony_ci		{ "vec2",	glu::TYPE_FLOAT_VEC2,	true	},
575e5c31af7Sopenharmony_ci		{ "vec3",	glu::TYPE_FLOAT_VEC3,	true	},
576e5c31af7Sopenharmony_ci		{ "vec4",	glu::TYPE_FLOAT_VEC4,	false	},
577e5c31af7Sopenharmony_ci		{ "mat2",	glu::TYPE_FLOAT_MAT2,	true	},
578e5c31af7Sopenharmony_ci		{ "mat2x3",	glu::TYPE_FLOAT_MAT2X3,	true	},
579e5c31af7Sopenharmony_ci		{ "mat2x4",	glu::TYPE_FLOAT_MAT2X4,	true	},
580e5c31af7Sopenharmony_ci		{ "mat3",	glu::TYPE_FLOAT_MAT3,	true	},
581e5c31af7Sopenharmony_ci		{ "mat3x2",	glu::TYPE_FLOAT_MAT3X2,	true	},
582e5c31af7Sopenharmony_ci		{ "mat3x4",	glu::TYPE_FLOAT_MAT3X4,	true	},
583e5c31af7Sopenharmony_ci		{ "mat4",	glu::TYPE_FLOAT_MAT4,	false	},
584e5c31af7Sopenharmony_ci		{ "mat4x2",	glu::TYPE_FLOAT_MAT4X2,	true	},
585e5c31af7Sopenharmony_ci		{ "mat4x3",	glu::TYPE_FLOAT_MAT4X3,	true	},
586e5c31af7Sopenharmony_ci	};
587e5c31af7Sopenharmony_ci
588e5c31af7Sopenharmony_ci	static const Target intTargets[] =
589e5c31af7Sopenharmony_ci	{
590e5c31af7Sopenharmony_ci		{ "int",	glu::TYPE_INT,			false	},
591e5c31af7Sopenharmony_ci		{ "ivec2",	glu::TYPE_INT_VEC2,		true	},
592e5c31af7Sopenharmony_ci		{ "ivec3",	glu::TYPE_INT_VEC3,		true	},
593e5c31af7Sopenharmony_ci		{ "ivec4",	glu::TYPE_INT_VEC4,		false	},
594e5c31af7Sopenharmony_ci	};
595e5c31af7Sopenharmony_ci
596e5c31af7Sopenharmony_ci	static const Target uintTargets[] =
597e5c31af7Sopenharmony_ci	{
598e5c31af7Sopenharmony_ci		{ "uint",	glu::TYPE_UINT,			false	},
599e5c31af7Sopenharmony_ci		{ "uvec2",	glu::TYPE_UINT_VEC2,	true	},
600e5c31af7Sopenharmony_ci		{ "uvec3",	glu::TYPE_UINT_VEC3,	true	},
601e5c31af7Sopenharmony_ci		{ "uvec4",	glu::TYPE_UINT_VEC4,	false	},
602e5c31af7Sopenharmony_ci	};
603e5c31af7Sopenharmony_ci
604e5c31af7Sopenharmony_ci	// float targets
605e5c31af7Sopenharmony_ci
606e5c31af7Sopenharmony_ci	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(floatTargets); ++targetNdx)
607e5c31af7Sopenharmony_ci	{
608e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(m_testCtx, floatTargets[targetNdx].name, (std::string("test with ") + floatTargets[targetNdx].name).c_str());
609e5c31af7Sopenharmony_ci		const bool					fullSet	= !floatTargets[targetNdx].reducedTestSets;
610e5c31af7Sopenharmony_ci
611e5c31af7Sopenharmony_ci#define ADD_CASE(X) group->addChild(AttributeCase::create<X>(m_context, floatTargets[targetNdx].dataType))
612e5c31af7Sopenharmony_ci#define ADD_REDUCED_CASE(X)	if (fullSet) ADD_CASE(X)
613e5c31af7Sopenharmony_ci
614e5c31af7Sopenharmony_ci		ADD_CASE		(LoaderVertexAttrib1f);
615e5c31af7Sopenharmony_ci		ADD_REDUCED_CASE(LoaderVertexAttrib2f);
616e5c31af7Sopenharmony_ci		ADD_REDUCED_CASE(LoaderVertexAttrib3f);
617e5c31af7Sopenharmony_ci		ADD_CASE		(LoaderVertexAttrib4f);
618e5c31af7Sopenharmony_ci
619e5c31af7Sopenharmony_ci		ADD_CASE		(LoaderVertexAttrib1fv);
620e5c31af7Sopenharmony_ci		ADD_REDUCED_CASE(LoaderVertexAttrib2fv);
621e5c31af7Sopenharmony_ci		ADD_REDUCED_CASE(LoaderVertexAttrib3fv);
622e5c31af7Sopenharmony_ci		ADD_CASE		(LoaderVertexAttrib4fv);
623e5c31af7Sopenharmony_ci
624e5c31af7Sopenharmony_ci#undef ADD_CASE
625e5c31af7Sopenharmony_ci#undef ADD_REDUCED_CASE
626e5c31af7Sopenharmony_ci
627e5c31af7Sopenharmony_ci		addChild(group);
628e5c31af7Sopenharmony_ci	}
629e5c31af7Sopenharmony_ci
630e5c31af7Sopenharmony_ci	// int targets
631e5c31af7Sopenharmony_ci
632e5c31af7Sopenharmony_ci	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(intTargets); ++targetNdx)
633e5c31af7Sopenharmony_ci	{
634e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(m_testCtx, intTargets[targetNdx].name, (std::string("test with ") + intTargets[targetNdx].name).c_str());
635e5c31af7Sopenharmony_ci
636e5c31af7Sopenharmony_ci#define ADD_CASE(X) group->addChild(AttributeCase::create<X>(m_context, intTargets[targetNdx].dataType))
637e5c31af7Sopenharmony_ci
638e5c31af7Sopenharmony_ci		ADD_CASE		(LoaderVertexAttribI4i);
639e5c31af7Sopenharmony_ci		ADD_CASE		(LoaderVertexAttribI4iv);
640e5c31af7Sopenharmony_ci
641e5c31af7Sopenharmony_ci#undef ADD_CASE
642e5c31af7Sopenharmony_ci
643e5c31af7Sopenharmony_ci		addChild(group);
644e5c31af7Sopenharmony_ci	}
645e5c31af7Sopenharmony_ci
646e5c31af7Sopenharmony_ci	// uint targets
647e5c31af7Sopenharmony_ci
648e5c31af7Sopenharmony_ci	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(uintTargets); ++targetNdx)
649e5c31af7Sopenharmony_ci	{
650e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(m_testCtx, uintTargets[targetNdx].name, (std::string("test with ") + uintTargets[targetNdx].name).c_str());
651e5c31af7Sopenharmony_ci
652e5c31af7Sopenharmony_ci#define ADD_CASE(X) group->addChild(AttributeCase::create<X>(m_context, uintTargets[targetNdx].dataType))
653e5c31af7Sopenharmony_ci
654e5c31af7Sopenharmony_ci		ADD_CASE		(LoaderVertexAttribI4ui);
655e5c31af7Sopenharmony_ci		ADD_CASE		(LoaderVertexAttribI4uiv);
656e5c31af7Sopenharmony_ci
657e5c31af7Sopenharmony_ci#undef ADD_CASE
658e5c31af7Sopenharmony_ci
659e5c31af7Sopenharmony_ci		addChild(group);
660e5c31af7Sopenharmony_ci	}
661e5c31af7Sopenharmony_ci}
662e5c31af7Sopenharmony_ci
663e5c31af7Sopenharmony_ci} // Functional
664e5c31af7Sopenharmony_ci} // gles3
665e5c31af7Sopenharmony_ci} // deqp
666