1e5c31af7Sopenharmony_ci#ifndef _GLSVERTEXARRAYTESTS_HPP
2e5c31af7Sopenharmony_ci#define _GLSVERTEXARRAYTESTS_HPP
3e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL (ES) Module
5e5c31af7Sopenharmony_ci * -----------------------------------------------
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
8e5c31af7Sopenharmony_ci *
9e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
10e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
11e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
14e5c31af7Sopenharmony_ci *
15e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
16e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
17e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
19e5c31af7Sopenharmony_ci * limitations under the License.
20e5c31af7Sopenharmony_ci *
21e5c31af7Sopenharmony_ci *//*!
22e5c31af7Sopenharmony_ci * \file
23e5c31af7Sopenharmony_ci * \brief Vertex array and buffer tests
24e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "tcuTestCase.hpp"
27e5c31af7Sopenharmony_ci#include "tcuVector.hpp"
28e5c31af7Sopenharmony_ci#include "tcuSurface.hpp"
29e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp"
30e5c31af7Sopenharmony_ci#include "gluCallLogWrapper.hpp"
31e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
32e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
33e5c31af7Sopenharmony_ci#include "deFloat16.h"
34e5c31af7Sopenharmony_ci#include "deMath.h"
35e5c31af7Sopenharmony_ci#include "tcuFloat.hpp"
36e5c31af7Sopenharmony_ci#include "tcuPixelFormat.hpp"
37e5c31af7Sopenharmony_ci#include "sglrContext.hpp"
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_cinamespace sglr
40e5c31af7Sopenharmony_ci{
41e5c31af7Sopenharmony_ci
42e5c31af7Sopenharmony_ciclass ReferenceContextBuffers;
43e5c31af7Sopenharmony_ciclass ReferenceContext;
44e5c31af7Sopenharmony_ciclass Context;
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_ci} // sglr
47e5c31af7Sopenharmony_ci
48e5c31af7Sopenharmony_cinamespace deqp
49e5c31af7Sopenharmony_ci{
50e5c31af7Sopenharmony_cinamespace gls
51e5c31af7Sopenharmony_ci{
52e5c31af7Sopenharmony_ci
53e5c31af7Sopenharmony_ciclass Array
54e5c31af7Sopenharmony_ci{
55e5c31af7Sopenharmony_cipublic:
56e5c31af7Sopenharmony_ci	enum Target
57e5c31af7Sopenharmony_ci	{
58e5c31af7Sopenharmony_ci		// \note [mika] Are these actualy used somewhere?
59e5c31af7Sopenharmony_ci		TARGET_ELEMENT_ARRAY = 0,
60e5c31af7Sopenharmony_ci		TARGET_ARRAY,
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_ci		TARGET_LAST
63e5c31af7Sopenharmony_ci	};
64e5c31af7Sopenharmony_ci
65e5c31af7Sopenharmony_ci	enum InputType
66e5c31af7Sopenharmony_ci	{
67e5c31af7Sopenharmony_ci		INPUTTYPE_FLOAT = 0,
68e5c31af7Sopenharmony_ci		INPUTTYPE_FIXED,
69e5c31af7Sopenharmony_ci		INPUTTYPE_DOUBLE,
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci		INPUTTYPE_BYTE,
72e5c31af7Sopenharmony_ci		INPUTTYPE_SHORT,
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ci		INPUTTYPE_UNSIGNED_BYTE,
75e5c31af7Sopenharmony_ci		INPUTTYPE_UNSIGNED_SHORT,
76e5c31af7Sopenharmony_ci
77e5c31af7Sopenharmony_ci		INPUTTYPE_INT,
78e5c31af7Sopenharmony_ci		INPUTTYPE_UNSIGNED_INT,
79e5c31af7Sopenharmony_ci		INPUTTYPE_HALF,
80e5c31af7Sopenharmony_ci		INPUTTYPE_UNSIGNED_INT_2_10_10_10,
81e5c31af7Sopenharmony_ci		INPUTTYPE_INT_2_10_10_10,
82e5c31af7Sopenharmony_ci
83e5c31af7Sopenharmony_ci		INPUTTYPE_LAST
84e5c31af7Sopenharmony_ci	};
85e5c31af7Sopenharmony_ci
86e5c31af7Sopenharmony_ci	enum OutputType
87e5c31af7Sopenharmony_ci	{
88e5c31af7Sopenharmony_ci		OUTPUTTYPE_FLOAT = 0,
89e5c31af7Sopenharmony_ci		OUTPUTTYPE_VEC2,
90e5c31af7Sopenharmony_ci		OUTPUTTYPE_VEC3,
91e5c31af7Sopenharmony_ci		OUTPUTTYPE_VEC4,
92e5c31af7Sopenharmony_ci
93e5c31af7Sopenharmony_ci		OUTPUTTYPE_INT,
94e5c31af7Sopenharmony_ci		OUTPUTTYPE_UINT,
95e5c31af7Sopenharmony_ci
96e5c31af7Sopenharmony_ci		OUTPUTTYPE_IVEC2,
97e5c31af7Sopenharmony_ci		OUTPUTTYPE_IVEC3,
98e5c31af7Sopenharmony_ci		OUTPUTTYPE_IVEC4,
99e5c31af7Sopenharmony_ci
100e5c31af7Sopenharmony_ci		OUTPUTTYPE_UVEC2,
101e5c31af7Sopenharmony_ci		OUTPUTTYPE_UVEC3,
102e5c31af7Sopenharmony_ci		OUTPUTTYPE_UVEC4,
103e5c31af7Sopenharmony_ci
104e5c31af7Sopenharmony_ci		OUTPUTTYPE_LAST
105e5c31af7Sopenharmony_ci	};
106e5c31af7Sopenharmony_ci
107e5c31af7Sopenharmony_ci	enum Usage
108e5c31af7Sopenharmony_ci	{
109e5c31af7Sopenharmony_ci		USAGE_DYNAMIC_DRAW = 0,
110e5c31af7Sopenharmony_ci		USAGE_STATIC_DRAW,
111e5c31af7Sopenharmony_ci		USAGE_STREAM_DRAW,
112e5c31af7Sopenharmony_ci
113e5c31af7Sopenharmony_ci		USAGE_STREAM_READ,
114e5c31af7Sopenharmony_ci		USAGE_STREAM_COPY,
115e5c31af7Sopenharmony_ci
116e5c31af7Sopenharmony_ci		USAGE_STATIC_READ,
117e5c31af7Sopenharmony_ci		USAGE_STATIC_COPY,
118e5c31af7Sopenharmony_ci
119e5c31af7Sopenharmony_ci		USAGE_DYNAMIC_READ,
120e5c31af7Sopenharmony_ci		USAGE_DYNAMIC_COPY,
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_ci		USAGE_LAST
123e5c31af7Sopenharmony_ci	};
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ci	enum Storage
126e5c31af7Sopenharmony_ci	{
127e5c31af7Sopenharmony_ci		STORAGE_USER = 0,
128e5c31af7Sopenharmony_ci		STORAGE_BUFFER,
129e5c31af7Sopenharmony_ci
130e5c31af7Sopenharmony_ci		STORAGE_LAST
131e5c31af7Sopenharmony_ci	};
132e5c31af7Sopenharmony_ci
133e5c31af7Sopenharmony_ci	enum Primitive
134e5c31af7Sopenharmony_ci	{
135e5c31af7Sopenharmony_ci		PRIMITIVE_POINTS = 0,
136e5c31af7Sopenharmony_ci		PRIMITIVE_TRIANGLES,
137e5c31af7Sopenharmony_ci		PRIMITIVE_TRIANGLE_FAN,
138e5c31af7Sopenharmony_ci		PRIMITIVE_TRIANGLE_STRIP,
139e5c31af7Sopenharmony_ci
140e5c31af7Sopenharmony_ci		PRIMITIVE_LAST
141e5c31af7Sopenharmony_ci	};
142e5c31af7Sopenharmony_ci
143e5c31af7Sopenharmony_ci	static std::string	targetToString		(Target target);
144e5c31af7Sopenharmony_ci	static std::string	inputTypeToString	(InputType type);
145e5c31af7Sopenharmony_ci	static std::string	outputTypeToString	(OutputType type);
146e5c31af7Sopenharmony_ci	static std::string	usageTypeToString	(Usage usage);
147e5c31af7Sopenharmony_ci	static std::string	storageToString		(Storage storage);
148e5c31af7Sopenharmony_ci	static std::string	primitiveToString	(Primitive primitive);
149e5c31af7Sopenharmony_ci	static int			inputTypeSize		(InputType type);
150e5c31af7Sopenharmony_ci
151e5c31af7Sopenharmony_ci	virtual				~Array				(void) {}
152e5c31af7Sopenharmony_ci	virtual void		data				(Target target, int size, const char* data, Usage usage) = 0;
153e5c31af7Sopenharmony_ci	virtual void		subdata				(Target target, int offset, int size, const char* data) = 0;
154e5c31af7Sopenharmony_ci	virtual void		bind				(int attribNdx, int offset, int size, InputType inType, OutputType outType, bool normalized, int stride) = 0;
155e5c31af7Sopenharmony_ci	virtual void		unBind				(void) = 0;
156e5c31af7Sopenharmony_ci
157e5c31af7Sopenharmony_ci	virtual bool		isBound				(void) const = 0;
158e5c31af7Sopenharmony_ci	virtual int			getComponentCount	(void) const = 0;
159e5c31af7Sopenharmony_ci	virtual Target		getTarget			(void) const = 0;
160e5c31af7Sopenharmony_ci	virtual InputType	getInputType		(void) const = 0;
161e5c31af7Sopenharmony_ci	virtual OutputType	getOutputType		(void) const = 0;
162e5c31af7Sopenharmony_ci	virtual Storage		getStorageType		(void) const = 0;
163e5c31af7Sopenharmony_ci	virtual bool		getNormalized		(void) const = 0;
164e5c31af7Sopenharmony_ci	virtual int			getStride			(void) const = 0;
165e5c31af7Sopenharmony_ci	virtual int			getAttribNdx		(void) const = 0;
166e5c31af7Sopenharmony_ci	virtual void		setAttribNdx		(int attribNdx) = 0;
167e5c31af7Sopenharmony_ci};
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ciclass ContextArray : public Array
170e5c31af7Sopenharmony_ci{
171e5c31af7Sopenharmony_cipublic:
172e5c31af7Sopenharmony_ci								ContextArray		(Storage storage, sglr::Context& context);
173e5c31af7Sopenharmony_ci	virtual						~ContextArray		(void);
174e5c31af7Sopenharmony_ci	virtual void				data				(Target target, int size, const char* data, Usage usage);
175e5c31af7Sopenharmony_ci	virtual void				subdata				(Target target, int offset, int size, const char* data);
176e5c31af7Sopenharmony_ci	virtual void				bind				(int attribNdx, int offset, int size, InputType inType, OutputType outType, bool normalized, int stride);
177e5c31af7Sopenharmony_ci	virtual void				bindIndexArray		(Array::Target storage);
178e5c31af7Sopenharmony_ci	virtual void				unBind				(void) { m_bound = false; }
179e5c31af7Sopenharmony_ci	virtual bool				isBound				(void) const { return m_bound; }
180e5c31af7Sopenharmony_ci
181e5c31af7Sopenharmony_ci	virtual int					getComponentCount	(void) const { return m_componentCount; }
182e5c31af7Sopenharmony_ci	virtual Array::Target		getTarget			(void) const { return m_target; }
183e5c31af7Sopenharmony_ci	virtual Array::InputType	getInputType		(void) const { return m_inputType; }
184e5c31af7Sopenharmony_ci	virtual Array::OutputType	getOutputType		(void) const { return m_outputType; }
185e5c31af7Sopenharmony_ci	virtual Array::Storage		getStorageType		(void) const { return m_storage; }
186e5c31af7Sopenharmony_ci	virtual bool				getNormalized		(void) const { return m_normalize; }
187e5c31af7Sopenharmony_ci	virtual int					getStride			(void) const { return m_stride; }
188e5c31af7Sopenharmony_ci	virtual int					getAttribNdx		(void) const { return m_attribNdx; }
189e5c31af7Sopenharmony_ci	virtual void				setAttribNdx		(int attribNdx) { m_attribNdx = attribNdx; }
190e5c31af7Sopenharmony_ci
191e5c31af7Sopenharmony_ci	void						glBind				(deUint32 loc);
192e5c31af7Sopenharmony_ci	static deUint32				targetToGL			(Array::Target target);
193e5c31af7Sopenharmony_ci	static deUint32				usageToGL			(Array::Usage usage);
194e5c31af7Sopenharmony_ci	static deUint32				inputTypeToGL		(Array::InputType type);
195e5c31af7Sopenharmony_ci	static std::string			outputTypeToGLType	(Array::OutputType type);
196e5c31af7Sopenharmony_ci	static deUint32				primitiveToGL		(Array::Primitive primitive);
197e5c31af7Sopenharmony_ci
198e5c31af7Sopenharmony_ciprivate:
199e5c31af7Sopenharmony_ci	Storage						m_storage;
200e5c31af7Sopenharmony_ci	sglr::Context&				m_ctx;
201e5c31af7Sopenharmony_ci	deUint32					m_glBuffer;
202e5c31af7Sopenharmony_ci
203e5c31af7Sopenharmony_ci	bool						m_bound;
204e5c31af7Sopenharmony_ci	int							m_attribNdx;
205e5c31af7Sopenharmony_ci	int							m_size;
206e5c31af7Sopenharmony_ci	char*						m_data;
207e5c31af7Sopenharmony_ci	int							m_componentCount;
208e5c31af7Sopenharmony_ci	Array::Target				m_target;
209e5c31af7Sopenharmony_ci	Array::InputType			m_inputType;
210e5c31af7Sopenharmony_ci	Array::OutputType			m_outputType;
211e5c31af7Sopenharmony_ci	bool						m_normalize;
212e5c31af7Sopenharmony_ci	int							m_stride;
213e5c31af7Sopenharmony_ci	int							m_offset;
214e5c31af7Sopenharmony_ci};
215e5c31af7Sopenharmony_ci
216e5c31af7Sopenharmony_ciclass ContextArrayPack
217e5c31af7Sopenharmony_ci{
218e5c31af7Sopenharmony_cipublic:
219e5c31af7Sopenharmony_ci								ContextArrayPack	(glu::RenderContext& renderCtx, sglr::Context& drawContext);
220e5c31af7Sopenharmony_ci	virtual						~ContextArrayPack	(void);
221e5c31af7Sopenharmony_ci	virtual Array*				getArray			(int i);
222e5c31af7Sopenharmony_ci	virtual int					getArrayCount		(void);
223e5c31af7Sopenharmony_ci	virtual	void				newArray			(Array::Storage storage);
224e5c31af7Sopenharmony_ci	virtual void				render				(Array::Primitive primitive, int firstVertex, int vertexCount, bool useVao, float coordScale, float colorScale);
225e5c31af7Sopenharmony_ci
226e5c31af7Sopenharmony_ci	const tcu::Surface&			getSurface			(void) const { return m_screen; }
227e5c31af7Sopenharmony_ciprivate:
228e5c31af7Sopenharmony_ci	void						updateProgram		(void);
229e5c31af7Sopenharmony_ci	glu::RenderContext&			m_renderCtx;
230e5c31af7Sopenharmony_ci	sglr::Context&				m_ctx;
231e5c31af7Sopenharmony_ci
232e5c31af7Sopenharmony_ci	std::vector<ContextArray*>	m_arrays;
233e5c31af7Sopenharmony_ci	sglr::ShaderProgram*		m_program;
234e5c31af7Sopenharmony_ci	tcu::Surface				m_screen;
235e5c31af7Sopenharmony_ci};
236e5c31af7Sopenharmony_ci
237e5c31af7Sopenharmony_ciclass GLValue
238e5c31af7Sopenharmony_ci{
239e5c31af7Sopenharmony_cipublic:
240e5c31af7Sopenharmony_ci	template<class Type>
241e5c31af7Sopenharmony_ci	class WrappedType
242e5c31af7Sopenharmony_ci	{
243e5c31af7Sopenharmony_ci	public:
244e5c31af7Sopenharmony_ci		static WrappedType<Type>	create			(Type value)							{ WrappedType<Type> v; v.m_value = value; return v; }
245e5c31af7Sopenharmony_ci		static WrappedType<Type>	fromFloat		(float value)							{ WrappedType<Type> v; v.m_value = (Type)value; return v; }
246e5c31af7Sopenharmony_ci		inline Type					getValue		(void) const							{ return m_value; }
247e5c31af7Sopenharmony_ci
248e5c31af7Sopenharmony_ci		inline WrappedType<Type>	operator+		(const WrappedType<Type>& other) const	{ return WrappedType<Type>::create((Type)(m_value + other.getValue())); }
249e5c31af7Sopenharmony_ci		inline WrappedType<Type>	operator*		(const WrappedType<Type>& other) const	{ return WrappedType<Type>::create((Type)(m_value * other.getValue())); }
250e5c31af7Sopenharmony_ci		inline WrappedType<Type>	operator/		(const WrappedType<Type>& other) const	{ return WrappedType<Type>::create((Type)(m_value / other.getValue())); }
251e5c31af7Sopenharmony_ci		inline WrappedType<Type>	operator%		(const WrappedType<Type>& other) const	{ return WrappedType<Type>::create((Type)(m_value % other.getValue())); }
252e5c31af7Sopenharmony_ci		inline WrappedType<Type>	operator-		(const WrappedType<Type>& other) const	{ return WrappedType<Type>::create((Type)(m_value - other.getValue())); }
253e5c31af7Sopenharmony_ci
254e5c31af7Sopenharmony_ci		inline WrappedType<Type>&	operator+=		(const WrappedType<Type>& other)		{ m_value += other.getValue(); return *this; }
255e5c31af7Sopenharmony_ci		inline WrappedType<Type>&	operator*=		(const WrappedType<Type>& other)		{ m_value *= other.getValue(); return *this; }
256e5c31af7Sopenharmony_ci		inline WrappedType<Type>&	operator/=		(const WrappedType<Type>& other)		{ m_value /= other.getValue(); return *this; }
257e5c31af7Sopenharmony_ci		inline WrappedType<Type>&	operator-=		(const WrappedType<Type>& other)		{ m_value -= other.getValue(); return *this; }
258e5c31af7Sopenharmony_ci
259e5c31af7Sopenharmony_ci		inline bool					operator==		(const WrappedType<Type>& other) const	{ return m_value == other.m_value; }
260e5c31af7Sopenharmony_ci		inline bool					operator!=		(const WrappedType<Type>& other) const	{ return m_value != other.m_value; }
261e5c31af7Sopenharmony_ci		inline bool					operator<		(const WrappedType<Type>& other) const	{ return m_value < other.m_value; }
262e5c31af7Sopenharmony_ci		inline bool					operator>		(const WrappedType<Type>& other) const	{ return m_value > other.m_value; }
263e5c31af7Sopenharmony_ci		inline bool					operator<=		(const WrappedType<Type>& other) const	{ return m_value <= other.m_value; }
264e5c31af7Sopenharmony_ci		inline bool					operator>=		(const WrappedType<Type>& other) const	{ return m_value >= other.m_value; }
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ci		inline						operator Type	(void) const							{ return m_value; }
267e5c31af7Sopenharmony_ci		template<class T>
268e5c31af7Sopenharmony_ci		inline T					to				(void) const							{ return (T)m_value; }
269e5c31af7Sopenharmony_ci	private:
270e5c31af7Sopenharmony_ci		Type	m_value;
271e5c31af7Sopenharmony_ci	};
272e5c31af7Sopenharmony_ci
273e5c31af7Sopenharmony_ci	template<class Type>
274e5c31af7Sopenharmony_ci	class WrappedFloatType
275e5c31af7Sopenharmony_ci	{
276e5c31af7Sopenharmony_ci	public:
277e5c31af7Sopenharmony_ci		static WrappedFloatType<Type>	create			(Type value)							{ WrappedFloatType<Type> v; v.m_value = value; return v; }
278e5c31af7Sopenharmony_ci		static WrappedFloatType<Type>	fromFloat		(float value)							{ WrappedFloatType<Type> v; v.m_value = (Type)value; return v; }
279e5c31af7Sopenharmony_ci		inline Type						getValue		(void) const							{ return m_value; }
280e5c31af7Sopenharmony_ci
281e5c31af7Sopenharmony_ci		inline WrappedFloatType<Type>	operator+		(const WrappedFloatType<Type>& other) const	{ return WrappedFloatType<Type>::create((Type)(m_value + other.getValue())); }
282e5c31af7Sopenharmony_ci		inline WrappedFloatType<Type>	operator*		(const WrappedFloatType<Type>& other) const	{ return WrappedFloatType<Type>::create((Type)(m_value * other.getValue())); }
283e5c31af7Sopenharmony_ci		inline WrappedFloatType<Type>	operator/		(const WrappedFloatType<Type>& other) const	{ return WrappedFloatType<Type>::create((Type)(m_value / other.getValue())); }
284e5c31af7Sopenharmony_ci		inline WrappedFloatType<Type>	operator%		(const WrappedFloatType<Type>& other) const	{ return WrappedFloatType<Type>::create((Type)(deMod(m_value, other.getValue()))); }
285e5c31af7Sopenharmony_ci		inline WrappedFloatType<Type>	operator-		(const WrappedFloatType<Type>& other) const	{ return WrappedFloatType<Type>::create((Type)(m_value - other.getValue())); }
286e5c31af7Sopenharmony_ci
287e5c31af7Sopenharmony_ci		inline WrappedFloatType<Type>&	operator+=		(const WrappedFloatType<Type>& other)		{ m_value += other.getValue(); return *this; }
288e5c31af7Sopenharmony_ci		inline WrappedFloatType<Type>&	operator*=		(const WrappedFloatType<Type>& other)		{ m_value *= other.getValue(); return *this; }
289e5c31af7Sopenharmony_ci		inline WrappedFloatType<Type>&	operator/=		(const WrappedFloatType<Type>& other)		{ m_value /= other.getValue(); return *this; }
290e5c31af7Sopenharmony_ci		inline WrappedFloatType<Type>&	operator-=		(const WrappedFloatType<Type>& other)		{ m_value -= other.getValue(); return *this; }
291e5c31af7Sopenharmony_ci
292e5c31af7Sopenharmony_ci		inline bool						operator==		(const WrappedFloatType<Type>& other) const	{ return m_value == other.m_value; }
293e5c31af7Sopenharmony_ci		inline bool						operator!=		(const WrappedFloatType<Type>& other) const	{ return m_value != other.m_value; }
294e5c31af7Sopenharmony_ci		inline bool						operator<		(const WrappedFloatType<Type>& other) const	{ return m_value < other.m_value; }
295e5c31af7Sopenharmony_ci		inline bool						operator>		(const WrappedFloatType<Type>& other) const	{ return m_value > other.m_value; }
296e5c31af7Sopenharmony_ci		inline bool						operator<=		(const WrappedFloatType<Type>& other) const	{ return m_value <= other.m_value; }
297e5c31af7Sopenharmony_ci		inline bool						operator>=		(const WrappedFloatType<Type>& other) const	{ return m_value >= other.m_value; }
298e5c31af7Sopenharmony_ci
299e5c31af7Sopenharmony_ci		inline							operator Type	(void) const							{ return m_value; }
300e5c31af7Sopenharmony_ci		template<class T>
301e5c31af7Sopenharmony_ci		inline T						to				(void) const							{ return (T)m_value; }
302e5c31af7Sopenharmony_ci	private:
303e5c31af7Sopenharmony_ci		Type	m_value;
304e5c31af7Sopenharmony_ci	};
305e5c31af7Sopenharmony_ci
306e5c31af7Sopenharmony_ci	typedef WrappedType<deInt16>		Short;
307e5c31af7Sopenharmony_ci	typedef WrappedType<deUint16>		Ushort;
308e5c31af7Sopenharmony_ci
309e5c31af7Sopenharmony_ci	typedef WrappedType<deInt8>			Byte;
310e5c31af7Sopenharmony_ci	typedef WrappedType<deUint8>		Ubyte;
311e5c31af7Sopenharmony_ci
312e5c31af7Sopenharmony_ci	typedef WrappedFloatType<float>		Float;
313e5c31af7Sopenharmony_ci	typedef WrappedFloatType<double>	Double;
314e5c31af7Sopenharmony_ci
315e5c31af7Sopenharmony_ci	typedef WrappedType<deInt32>		Int;
316e5c31af7Sopenharmony_ci	typedef WrappedType<deUint32>		Uint;
317e5c31af7Sopenharmony_ci
318e5c31af7Sopenharmony_ci	class Half
319e5c31af7Sopenharmony_ci	{
320e5c31af7Sopenharmony_ci	public:
321e5c31af7Sopenharmony_ci		static Half			create			(float value)				{ Half h; h.m_value = floatToHalf(value); return h; }
322e5c31af7Sopenharmony_ci		static Half			fromFloat		(float value)				{ Half h; h.m_value = floatToHalf(value); return h; }
323e5c31af7Sopenharmony_ci		inline deFloat16	getValue		(void) const				{ return m_value; }
324e5c31af7Sopenharmony_ci
325e5c31af7Sopenharmony_ci		inline Half			operator+		(const Half& other) const	{ return create(halfToFloat(m_value) + halfToFloat(other.getValue())); }
326e5c31af7Sopenharmony_ci		inline Half			operator*		(const Half& other) const	{ return create(halfToFloat(m_value) * halfToFloat(other.getValue())); }
327e5c31af7Sopenharmony_ci		inline Half			operator/		(const Half& other) const	{ return create(halfToFloat(m_value) / halfToFloat(other.getValue())); }
328e5c31af7Sopenharmony_ci		inline Half			operator%		(const Half& other) const	{ return create(deFloatMod(halfToFloat(m_value), halfToFloat(other.getValue()))); }
329e5c31af7Sopenharmony_ci		inline Half			operator-		(const Half& other) const	{ return create(halfToFloat(m_value) - halfToFloat(other.getValue())); }
330e5c31af7Sopenharmony_ci
331e5c31af7Sopenharmony_ci		inline Half&		operator+=		(const Half& other)			{ m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value)); return *this; }
332e5c31af7Sopenharmony_ci		inline Half&		operator*=		(const Half& other)			{ m_value = floatToHalf(halfToFloat(other.getValue()) * halfToFloat(m_value)); return *this; }
333e5c31af7Sopenharmony_ci		inline Half&		operator/=		(const Half& other)			{ m_value = floatToHalf(halfToFloat(other.getValue()) / halfToFloat(m_value)); return *this; }
334e5c31af7Sopenharmony_ci		inline Half&		operator-=		(const Half& other)			{ m_value = floatToHalf(halfToFloat(other.getValue()) - halfToFloat(m_value)); return *this; }
335e5c31af7Sopenharmony_ci
336e5c31af7Sopenharmony_ci		inline bool			operator==		(const Half& other) const	{ return m_value == other.m_value; }
337e5c31af7Sopenharmony_ci		inline bool			operator!=		(const Half& other) const	{ return m_value != other.m_value; }
338e5c31af7Sopenharmony_ci		inline bool			operator<		(const Half& other) const	{ return halfToFloat(m_value) < halfToFloat(other.m_value); }
339e5c31af7Sopenharmony_ci		inline bool			operator>		(const Half& other) const	{ return halfToFloat(m_value) > halfToFloat(other.m_value); }
340e5c31af7Sopenharmony_ci		inline bool			operator<=		(const Half& other) const	{ return halfToFloat(m_value) <= halfToFloat(other.m_value); }
341e5c31af7Sopenharmony_ci		inline bool			operator>=		(const Half& other) const	{ return halfToFloat(m_value) >= halfToFloat(other.m_value); }
342e5c31af7Sopenharmony_ci
343e5c31af7Sopenharmony_ci		template<class T>
344e5c31af7Sopenharmony_ci		inline T			to				(void) const				{ return (T)halfToFloat(m_value); }
345e5c31af7Sopenharmony_ci
346e5c31af7Sopenharmony_ci		inline static deFloat16	floatToHalf		(float f);
347e5c31af7Sopenharmony_ci		inline static float		halfToFloat		(deFloat16 h);
348e5c31af7Sopenharmony_ci	private:
349e5c31af7Sopenharmony_ci		deFloat16 m_value;
350e5c31af7Sopenharmony_ci	};
351e5c31af7Sopenharmony_ci
352e5c31af7Sopenharmony_ci	class Fixed
353e5c31af7Sopenharmony_ci	{
354e5c31af7Sopenharmony_ci	public:
355e5c31af7Sopenharmony_ci		static Fixed		create			(deInt32 value)				{ Fixed v; v.m_value = value; return v; }
356e5c31af7Sopenharmony_ci		static Fixed		fromFloat		(float value)				{ Fixed v; v.m_value = (deInt32)value; return v; }
357e5c31af7Sopenharmony_ci		inline deInt32		getValue		(void) const				{ return m_value; }
358e5c31af7Sopenharmony_ci
359e5c31af7Sopenharmony_ci		inline Fixed		operator+		(const Fixed& other) const	{ return create(m_value + other.getValue()); }
360e5c31af7Sopenharmony_ci		inline Fixed		operator*		(const Fixed& other) const	{ return create(m_value * other.getValue()); }
361e5c31af7Sopenharmony_ci		inline Fixed		operator/		(const Fixed& other) const	{ return create(m_value / other.getValue()); }
362e5c31af7Sopenharmony_ci		inline Fixed		operator%		(const Fixed& other) const	{ return create(m_value % other.getValue()); }
363e5c31af7Sopenharmony_ci		inline Fixed		operator-		(const Fixed& other) const	{ return create(m_value - other.getValue()); }
364e5c31af7Sopenharmony_ci
365e5c31af7Sopenharmony_ci		inline Fixed&		operator+=		(const Fixed& other)		{ m_value += other.getValue(); return *this; }
366e5c31af7Sopenharmony_ci		inline Fixed&		operator*=		(const Fixed& other)		{ m_value *= other.getValue(); return *this; }
367e5c31af7Sopenharmony_ci		inline Fixed&		operator/=		(const Fixed& other)		{ m_value /= other.getValue(); return *this; }
368e5c31af7Sopenharmony_ci		inline Fixed&		operator-=		(const Fixed& other)		{ m_value -= other.getValue(); return *this; }
369e5c31af7Sopenharmony_ci
370e5c31af7Sopenharmony_ci		inline bool			operator==		(const Fixed& other) const	{ return m_value == other.m_value; }
371e5c31af7Sopenharmony_ci		inline bool			operator!=		(const Fixed& other) const	{ return m_value != other.m_value; }
372e5c31af7Sopenharmony_ci		inline bool			operator<		(const Fixed& other) const	{ return m_value < other.m_value; }
373e5c31af7Sopenharmony_ci		inline bool			operator>		(const Fixed& other) const	{ return m_value > other.m_value; }
374e5c31af7Sopenharmony_ci		inline bool			operator<=		(const Fixed& other) const	{ return m_value <= other.m_value; }
375e5c31af7Sopenharmony_ci		inline bool			operator>=		(const Fixed& other) const	{ return m_value >= other.m_value; }
376e5c31af7Sopenharmony_ci
377e5c31af7Sopenharmony_ci		inline				operator deInt32 (void) const				{ return m_value; }
378e5c31af7Sopenharmony_ci		template<class T>
379e5c31af7Sopenharmony_ci		inline T			to				(void) const				{ return (T)m_value; }
380e5c31af7Sopenharmony_ci	private:
381e5c31af7Sopenharmony_ci		deInt32				m_value;
382e5c31af7Sopenharmony_ci	};
383e5c31af7Sopenharmony_ci
384e5c31af7Sopenharmony_ci	// \todo [mika] This is pretty messy
385e5c31af7Sopenharmony_ci						GLValue			(void)			: type(Array::INPUTTYPE_LAST) {}
386e5c31af7Sopenharmony_ci	explicit			GLValue			(Float value)	: type(Array::INPUTTYPE_FLOAT),				fl(value)	{}
387e5c31af7Sopenharmony_ci	explicit			GLValue			(Fixed value)	: type(Array::INPUTTYPE_FIXED),				fi(value)	{}
388e5c31af7Sopenharmony_ci	explicit			GLValue			(Byte value)	: type(Array::INPUTTYPE_BYTE),				b(value)	{}
389e5c31af7Sopenharmony_ci	explicit			GLValue			(Ubyte value)	: type(Array::INPUTTYPE_UNSIGNED_BYTE),		ub(value)	{}
390e5c31af7Sopenharmony_ci	explicit			GLValue			(Short value)	: type(Array::INPUTTYPE_SHORT),				s(value)	{}
391e5c31af7Sopenharmony_ci	explicit			GLValue			(Ushort value)	: type(Array::INPUTTYPE_UNSIGNED_SHORT),	us(value)	{}
392e5c31af7Sopenharmony_ci	explicit			GLValue			(Int value)		: type(Array::INPUTTYPE_INT),				i(value)	{}
393e5c31af7Sopenharmony_ci	explicit			GLValue			(Uint value)	: type(Array::INPUTTYPE_UNSIGNED_INT),		ui(value)	{}
394e5c31af7Sopenharmony_ci	explicit			GLValue			(Half value)	: type(Array::INPUTTYPE_HALF),				h(value)	{}
395e5c31af7Sopenharmony_ci	explicit			GLValue			(Double value)	: type(Array::INPUTTYPE_DOUBLE),			d(value)	{}
396e5c31af7Sopenharmony_ci
397e5c31af7Sopenharmony_ci	float				toFloat			(void) const;
398e5c31af7Sopenharmony_ci
399e5c31af7Sopenharmony_ci	static GLValue		getMaxValue		(Array::InputType type);
400e5c31af7Sopenharmony_ci	static GLValue		getMinValue		(Array::InputType type);
401e5c31af7Sopenharmony_ci
402e5c31af7Sopenharmony_ci	Array::InputType	type;
403e5c31af7Sopenharmony_ci
404e5c31af7Sopenharmony_ci	union
405e5c31af7Sopenharmony_ci	{
406e5c31af7Sopenharmony_ci		Float		fl;
407e5c31af7Sopenharmony_ci		Fixed		fi;
408e5c31af7Sopenharmony_ci		Double		d;
409e5c31af7Sopenharmony_ci		Byte		b;
410e5c31af7Sopenharmony_ci		Ubyte		ub;
411e5c31af7Sopenharmony_ci		Short		s;
412e5c31af7Sopenharmony_ci		Ushort		us;
413e5c31af7Sopenharmony_ci		Int			i;
414e5c31af7Sopenharmony_ci		Uint		ui;
415e5c31af7Sopenharmony_ci		Half		h;
416e5c31af7Sopenharmony_ci	};
417e5c31af7Sopenharmony_ci};
418e5c31af7Sopenharmony_ci
419e5c31af7Sopenharmony_ciclass VertexArrayTest : public tcu::TestCase
420e5c31af7Sopenharmony_ci{
421e5c31af7Sopenharmony_cipublic:
422e5c31af7Sopenharmony_ci									VertexArrayTest		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name ,const char* desc);
423e5c31af7Sopenharmony_ci	virtual							~VertexArrayTest	(void);
424e5c31af7Sopenharmony_ci	virtual void					init				(void);
425e5c31af7Sopenharmony_ci	virtual void					deinit				(void);
426e5c31af7Sopenharmony_ci
427e5c31af7Sopenharmony_ciprotected:
428e5c31af7Sopenharmony_ci									VertexArrayTest		(const VertexArrayTest& other);
429e5c31af7Sopenharmony_ci	VertexArrayTest&				operator=			(const VertexArrayTest& other);
430e5c31af7Sopenharmony_ci
431e5c31af7Sopenharmony_ci	void							compare				(void);
432e5c31af7Sopenharmony_ci
433e5c31af7Sopenharmony_ci	glu::RenderContext&				m_renderCtx;
434e5c31af7Sopenharmony_ci
435e5c31af7Sopenharmony_ci	sglr::ReferenceContextBuffers*	m_refBuffers;
436e5c31af7Sopenharmony_ci	sglr::ReferenceContext*			m_refContext;
437e5c31af7Sopenharmony_ci	sglr::Context*					m_glesContext;
438e5c31af7Sopenharmony_ci
439e5c31af7Sopenharmony_ci	ContextArrayPack*				m_glArrayPack;
440e5c31af7Sopenharmony_ci	ContextArrayPack*				m_rrArrayPack;
441e5c31af7Sopenharmony_ci	bool							m_isOk;
442e5c31af7Sopenharmony_ci
443e5c31af7Sopenharmony_ci	int								m_maxDiffRed;
444e5c31af7Sopenharmony_ci	int								m_maxDiffGreen;
445e5c31af7Sopenharmony_ci	int								m_maxDiffBlue;
446e5c31af7Sopenharmony_ci};
447e5c31af7Sopenharmony_ci
448e5c31af7Sopenharmony_ciclass MultiVertexArrayTest : public VertexArrayTest
449e5c31af7Sopenharmony_ci{
450e5c31af7Sopenharmony_cipublic:
451e5c31af7Sopenharmony_ci	class Spec
452e5c31af7Sopenharmony_ci	{
453e5c31af7Sopenharmony_ci	public:
454e5c31af7Sopenharmony_ci		class ArraySpec
455e5c31af7Sopenharmony_ci		{
456e5c31af7Sopenharmony_ci		public:
457e5c31af7Sopenharmony_ci								ArraySpec	(Array::InputType inputType, Array::OutputType outputType, Array::Storage storage, Array::Usage usage, int componetCount, int offset, int stride, bool normalize, GLValue min, GLValue max);
458e5c31af7Sopenharmony_ci
459e5c31af7Sopenharmony_ci			Array::InputType	inputType;
460e5c31af7Sopenharmony_ci			Array::OutputType	outputType;
461e5c31af7Sopenharmony_ci			Array::Storage		storage;
462e5c31af7Sopenharmony_ci			Array::Usage		usage;
463e5c31af7Sopenharmony_ci			int					componentCount;
464e5c31af7Sopenharmony_ci			int					offset;
465e5c31af7Sopenharmony_ci			int					stride;
466e5c31af7Sopenharmony_ci			bool				normalize;
467e5c31af7Sopenharmony_ci			GLValue				min;
468e5c31af7Sopenharmony_ci			GLValue				max;
469e5c31af7Sopenharmony_ci		};
470e5c31af7Sopenharmony_ci
471e5c31af7Sopenharmony_ci		std::string				getName		(void) const;
472e5c31af7Sopenharmony_ci		std::string				getDesc		(void) const;
473e5c31af7Sopenharmony_ci
474e5c31af7Sopenharmony_ci		Array::Primitive		primitive;
475e5c31af7Sopenharmony_ci		int						drawCount;			//!<Number of primitives to draw
476e5c31af7Sopenharmony_ci		int						first;
477e5c31af7Sopenharmony_ci
478e5c31af7Sopenharmony_ci		std::vector<ArraySpec>	arrays;
479e5c31af7Sopenharmony_ci	};
480e5c31af7Sopenharmony_ci
481e5c31af7Sopenharmony_ci							MultiVertexArrayTest	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const Spec& spec, const char* name, const char* desc);
482e5c31af7Sopenharmony_ci	virtual					~MultiVertexArrayTest	(void);
483e5c31af7Sopenharmony_ci	virtual IterateResult	iterate					(void);
484e5c31af7Sopenharmony_ci
485e5c31af7Sopenharmony_ciprivate:
486e5c31af7Sopenharmony_ci	bool					isUnalignedBufferOffsetTest		(void) const;
487e5c31af7Sopenharmony_ci	bool					isUnalignedBufferStrideTest		(void) const;
488e5c31af7Sopenharmony_ci
489e5c31af7Sopenharmony_ci	Spec					m_spec;
490e5c31af7Sopenharmony_ci	int						m_iteration;
491e5c31af7Sopenharmony_ci};
492e5c31af7Sopenharmony_ci
493e5c31af7Sopenharmony_ciinline deFloat16 GLValue::Half::floatToHalf (float f)
494e5c31af7Sopenharmony_ci{
495e5c31af7Sopenharmony_ci	// No denorm support.
496e5c31af7Sopenharmony_ci	tcu::Float<deUint16, 5, 10, 15, tcu::FLOAT_HAS_SIGN> v(f);
497e5c31af7Sopenharmony_ci	DE_ASSERT(!v.isNaN() && !v.isInf());
498e5c31af7Sopenharmony_ci	return v.bits();
499e5c31af7Sopenharmony_ci}
500e5c31af7Sopenharmony_ci
501e5c31af7Sopenharmony_ciinline float GLValue::Half::halfToFloat (deFloat16 h)
502e5c31af7Sopenharmony_ci{
503e5c31af7Sopenharmony_ci	return tcu::Float16((deUint16)h).asFloat();
504e5c31af7Sopenharmony_ci}
505e5c31af7Sopenharmony_ci
506e5c31af7Sopenharmony_ci} // gls
507e5c31af7Sopenharmony_ci} // deqp
508e5c31af7Sopenharmony_ci
509e5c31af7Sopenharmony_ci#endif // _GLSVERTEXARRAYTESTS_HPP
510