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