Add packaging for TIZEN
[platform/upstream/VK-GL-CTS.git] / modules / glshared / glsVertexArrayTests.hpp
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
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);
178         virtual void                            unBind                          (void) { m_bound = false; }
179         virtual bool                            isBound                         (void) const { return m_bound; }
180
181         virtual int                                     getComponentCount       (void) const { return m_componentCount; }
182         virtual Array::Target           getTarget                       (void) const { return m_target; }
183         virtual Array::InputType        getInputType            (void) const { return m_inputType; }
184         virtual Array::OutputType       getOutputType           (void) const { return m_outputType; }
185         virtual Array::Storage          getStorageType          (void) const { return m_storage; }
186         virtual bool                            getNormalized           (void) const { return m_normalize; }
187         virtual int                                     getStride                       (void) const { return m_stride; }
188         virtual int                                     getAttribNdx            (void) const { return m_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
226         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:
244                 static WrappedType<Type>        create                  (Type value)                                                    { WrappedType<Type> v; v.m_value = value; return v; }
245                 static WrappedType<Type>        fromFloat               (float value)                                                   { WrappedType<Type> v; v.m_value = (Type)value; return v; }
246                 inline Type                                     getValue                (void) const                                                    { return m_value; }
247
248                 inline WrappedType<Type>        operator+               (const WrappedType<Type>& other) const  { return WrappedType<Type>::create((Type)(m_value + other.getValue())); }
249                 inline WrappedType<Type>        operator*               (const WrappedType<Type>& other) const  { return WrappedType<Type>::create((Type)(m_value * other.getValue())); }
250                 inline WrappedType<Type>        operator/               (const WrappedType<Type>& other) const  { return WrappedType<Type>::create((Type)(m_value / other.getValue())); }
251                 inline WrappedType<Type>        operator%               (const WrappedType<Type>& other) const  { return WrappedType<Type>::create((Type)(m_value % other.getValue())); }
252                 inline WrappedType<Type>        operator-               (const WrappedType<Type>& other) const  { return WrappedType<Type>::create((Type)(m_value - other.getValue())); }
253
254                 inline WrappedType<Type>&       operator+=              (const WrappedType<Type>& other)                { m_value += other.getValue(); return *this; }
255                 inline WrappedType<Type>&       operator*=              (const WrappedType<Type>& other)                { m_value *= other.getValue(); return *this; }
256                 inline WrappedType<Type>&       operator/=              (const WrappedType<Type>& other)                { m_value /= other.getValue(); return *this; }
257                 inline WrappedType<Type>&       operator-=              (const WrappedType<Type>& other)                { m_value -= other.getValue(); return *this; }
258
259                 inline bool                                     operator==              (const WrappedType<Type>& other) const  { return m_value == other.m_value; }
260                 inline bool                                     operator!=              (const WrappedType<Type>& other) const  { return m_value != other.m_value; }
261                 inline bool                                     operator<               (const WrappedType<Type>& other) const  { return m_value < other.m_value; }
262                 inline bool                                     operator>               (const WrappedType<Type>& other) const  { return m_value > other.m_value; }
263                 inline bool                                     operator<=              (const WrappedType<Type>& other) const  { return m_value <= other.m_value; }
264                 inline bool                                     operator>=              (const WrappedType<Type>& other) const  { return m_value >= other.m_value; }
265
266                 inline                                          operator Type   (void) const                                                    { return m_value; }
267                 template<class T>
268                 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:
277                 static WrappedFloatType<Type>   create                  (Type value)                                                    { WrappedFloatType<Type> v; v.m_value = value; return v; }
278                 static WrappedFloatType<Type>   fromFloat               (float value)                                                   { WrappedFloatType<Type> v; v.m_value = (Type)value; return v; }
279                 inline Type                                             getValue                (void) const                                                    { return m_value; }
280
281                 inline WrappedFloatType<Type>   operator+               (const WrappedFloatType<Type>& other) const     { return WrappedFloatType<Type>::create((Type)(m_value + other.getValue())); }
282                 inline WrappedFloatType<Type>   operator*               (const WrappedFloatType<Type>& other) const     { return WrappedFloatType<Type>::create((Type)(m_value * other.getValue())); }
283                 inline WrappedFloatType<Type>   operator/               (const WrappedFloatType<Type>& other) const     { return WrappedFloatType<Type>::create((Type)(m_value / other.getValue())); }
284                 inline WrappedFloatType<Type>   operator%               (const WrappedFloatType<Type>& other) const     { return WrappedFloatType<Type>::create((Type)(deMod(m_value, other.getValue()))); }
285                 inline WrappedFloatType<Type>   operator-               (const WrappedFloatType<Type>& other) const     { return WrappedFloatType<Type>::create((Type)(m_value - other.getValue())); }
286
287                 inline WrappedFloatType<Type>&  operator+=              (const WrappedFloatType<Type>& other)           { m_value += other.getValue(); return *this; }
288                 inline WrappedFloatType<Type>&  operator*=              (const WrappedFloatType<Type>& other)           { m_value *= other.getValue(); return *this; }
289                 inline WrappedFloatType<Type>&  operator/=              (const WrappedFloatType<Type>& other)           { m_value /= other.getValue(); return *this; }
290                 inline WrappedFloatType<Type>&  operator-=              (const WrappedFloatType<Type>& other)           { m_value -= other.getValue(); return *this; }
291
292                 inline bool                                             operator==              (const WrappedFloatType<Type>& other) const     { return m_value == other.m_value; }
293                 inline bool                                             operator!=              (const WrappedFloatType<Type>& other) const     { return m_value != other.m_value; }
294                 inline bool                                             operator<               (const WrappedFloatType<Type>& other) const     { return m_value < other.m_value; }
295                 inline bool                                             operator>               (const WrappedFloatType<Type>& other) const     { return m_value > other.m_value; }
296                 inline bool                                             operator<=              (const WrappedFloatType<Type>& other) const     { return m_value <= other.m_value; }
297                 inline bool                                             operator>=              (const WrappedFloatType<Type>& other) const     { return m_value >= other.m_value; }
298
299                 inline                                                  operator Type   (void) const                                                    { return m_value; }
300                 template<class T>
301                 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:
321                 static Half                     create                  (float value)                           { Half h; h.m_value = floatToHalf(value); return h; }
322                 static Half                     fromFloat               (float value)                           { Half h; h.m_value = floatToHalf(value); return h; }
323                 inline deFloat16        getValue                (void) const                            { return m_value; }
324
325                 inline Half                     operator+               (const Half& other) const       { return create(halfToFloat(m_value) + halfToFloat(other.getValue())); }
326                 inline Half                     operator*               (const Half& other) const       { return create(halfToFloat(m_value) * halfToFloat(other.getValue())); }
327                 inline Half                     operator/               (const Half& other) const       { return create(halfToFloat(m_value) / halfToFloat(other.getValue())); }
328                 inline Half                     operator%               (const Half& other) const       { return create(deFloatMod(halfToFloat(m_value), halfToFloat(other.getValue()))); }
329                 inline Half                     operator-               (const Half& other) const       { return create(halfToFloat(m_value) - halfToFloat(other.getValue())); }
330
331                 inline Half&            operator+=              (const Half& other)                     { m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value)); return *this; }
332                 inline Half&            operator*=              (const Half& other)                     { m_value = floatToHalf(halfToFloat(other.getValue()) * halfToFloat(m_value)); return *this; }
333                 inline Half&            operator/=              (const Half& other)                     { m_value = floatToHalf(halfToFloat(other.getValue()) / halfToFloat(m_value)); return *this; }
334                 inline Half&            operator-=              (const Half& other)                     { m_value = floatToHalf(halfToFloat(other.getValue()) - halfToFloat(m_value)); return *this; }
335
336                 inline bool                     operator==              (const Half& other) const       { return m_value == other.m_value; }
337                 inline bool                     operator!=              (const Half& other) const       { return m_value != other.m_value; }
338                 inline bool                     operator<               (const Half& other) const       { return halfToFloat(m_value) < halfToFloat(other.m_value); }
339                 inline bool                     operator>               (const Half& other) const       { return halfToFloat(m_value) > halfToFloat(other.m_value); }
340                 inline bool                     operator<=              (const Half& other) const       { return halfToFloat(m_value) <= halfToFloat(other.m_value); }
341                 inline bool                     operator>=              (const Half& other) const       { return halfToFloat(m_value) >= halfToFloat(other.m_value); }
342
343                 template<class T>
344                 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:
355                 static Fixed            create                  (deInt32 value)                         { Fixed v; v.m_value = value; return v; }
356                 static Fixed            fromFloat               (float value)                           { Fixed v; v.m_value = (deInt32)(value * 32768.0f); return v; }
357                 inline deInt32          getValue                (void) const                            { return m_value; }
358
359                 inline Fixed            operator+               (const Fixed& other) const      { return create(m_value + other.getValue()); }
360                 inline Fixed            operator*               (const Fixed& other) const      { return create(m_value * other.getValue()); }
361                 inline Fixed            operator/               (const Fixed& other) const      { return create(m_value / other.getValue()); }
362                 inline Fixed            operator%               (const Fixed& other) const      { return create(m_value % other.getValue()); }
363                 inline Fixed            operator-               (const Fixed& other) const      { return create(m_value - other.getValue()); }
364
365                 inline Fixed&           operator+=              (const Fixed& other)            { m_value += other.getValue(); return *this; }
366                 inline Fixed&           operator*=              (const Fixed& other)            { m_value *= other.getValue(); return *this; }
367                 inline Fixed&           operator/=              (const Fixed& other)            { m_value /= other.getValue(); return *this; }
368                 inline Fixed&           operator-=              (const Fixed& other)            { m_value -= other.getValue(); return *this; }
369
370                 inline bool                     operator==              (const Fixed& other) const      { return m_value == other.m_value; }
371                 inline bool                     operator!=              (const Fixed& other) const      { return m_value != other.m_value; }
372                 inline bool                     operator<               (const Fixed& other) const      { return m_value < other.m_value; }
373                 inline bool                     operator>               (const Fixed& other) const      { return m_value > other.m_value; }
374                 inline bool                     operator<=              (const Fixed& other) const      { return m_value <= other.m_value; }
375                 inline bool                     operator>=              (const Fixed& other) const      { return m_value >= other.m_value; }
376
377                 inline                          operator deInt32 (void) const                           { return m_value; }
378                 template<class T>
379                 inline T                        to                              (void) const                            { return (T)m_value; }
380         private:
381                 deInt32                         m_value;
382         };
383
384         // \todo [mika] This is pretty messy
385                                                 GLValue                 (void)                  : type(Array::INPUTTYPE_LAST) {}
386         explicit                        GLValue                 (Float value)   : type(Array::INPUTTYPE_FLOAT),                         fl(value)       {}
387         explicit                        GLValue                 (Fixed value)   : type(Array::INPUTTYPE_FIXED),                         fi(value)       {}
388         explicit                        GLValue                 (Byte value)    : type(Array::INPUTTYPE_BYTE),                          b(value)        {}
389         explicit                        GLValue                 (Ubyte value)   : type(Array::INPUTTYPE_UNSIGNED_BYTE),         ub(value)       {}
390         explicit                        GLValue                 (Short value)   : type(Array::INPUTTYPE_SHORT),                         s(value)        {}
391         explicit                        GLValue                 (Ushort value)  : type(Array::INPUTTYPE_UNSIGNED_SHORT),        us(value)       {}
392         explicit                        GLValue                 (Int value)             : type(Array::INPUTTYPE_INT),                           i(value)        {}
393         explicit                        GLValue                 (Uint value)    : type(Array::INPUTTYPE_UNSIGNED_INT),          ui(value)       {}
394         explicit                        GLValue                 (Half value)    : type(Array::INPUTTYPE_HALF),                          h(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
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
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