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