xref: /aosp_15_r20/external/deqp/modules/glshared/glsVertexArrayTests.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 } // namespace 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     {
153     }
154     virtual void data(Target target, int size, const char *data, Usage usage)   = 0;
155     virtual void subdata(Target target, int offset, int size, const char *data) = 0;
156     virtual void bind(int attribNdx, int offset, int size, InputType inType, OutputType outType, bool normalized,
157                       int stride)                                               = 0;
158     virtual void unBind(void)                                                   = 0;
159 
160     virtual bool isBound(void) const             = 0;
161     virtual int getComponentCount(void) const    = 0;
162     virtual Target getTarget(void) const         = 0;
163     virtual InputType getInputType(void) const   = 0;
164     virtual OutputType getOutputType(void) const = 0;
165     virtual Storage getStorageType(void) const   = 0;
166     virtual bool getNormalized(void) const       = 0;
167     virtual int getStride(void) const            = 0;
168     virtual int getAttribNdx(void) const         = 0;
169     virtual void setAttribNdx(int attribNdx)     = 0;
170 };
171 
172 class ContextArray : public Array
173 {
174 public:
175     ContextArray(Storage storage, sglr::Context &context);
176     virtual ~ContextArray(void);
177     virtual void data(Target target, int size, const char *data, Usage usage);
178     virtual void subdata(Target target, int offset, int size, const char *data);
179     virtual void bind(int attribNdx, int offset, int size, InputType inType, OutputType outType, bool normalized,
180                       int stride);
181     virtual void bindIndexArray(Array::Target storage);
unBind(void)182     virtual void unBind(void)
183     {
184         m_bound = false;
185     }
isBound(void) const186     virtual bool isBound(void) const
187     {
188         return m_bound;
189     }
190 
getComponentCount(void) const191     virtual int getComponentCount(void) const
192     {
193         return m_componentCount;
194     }
getTarget(void) const195     virtual Array::Target getTarget(void) const
196     {
197         return m_target;
198     }
getInputType(void) const199     virtual Array::InputType getInputType(void) const
200     {
201         return m_inputType;
202     }
getOutputType(void) const203     virtual Array::OutputType getOutputType(void) const
204     {
205         return m_outputType;
206     }
getStorageType(void) const207     virtual Array::Storage getStorageType(void) const
208     {
209         return m_storage;
210     }
getNormalized(void) const211     virtual bool getNormalized(void) const
212     {
213         return m_normalize;
214     }
getStride(void) const215     virtual int getStride(void) const
216     {
217         return m_stride;
218     }
getAttribNdx(void) const219     virtual int getAttribNdx(void) const
220     {
221         return m_attribNdx;
222     }
setAttribNdx(int attribNdx)223     virtual void setAttribNdx(int attribNdx)
224     {
225         m_attribNdx = attribNdx;
226     }
227 
228     void glBind(uint32_t loc);
229     static uint32_t targetToGL(Array::Target target);
230     static uint32_t usageToGL(Array::Usage usage);
231     static uint32_t inputTypeToGL(Array::InputType type);
232     static std::string outputTypeToGLType(Array::OutputType type);
233     static uint32_t primitiveToGL(Array::Primitive primitive);
234 
235 private:
236     Storage m_storage;
237     sglr::Context &m_ctx;
238     uint32_t m_glBuffer;
239 
240     bool m_bound;
241     int m_attribNdx;
242     int m_size;
243     char *m_data;
244     int m_componentCount;
245     Array::Target m_target;
246     Array::InputType m_inputType;
247     Array::OutputType m_outputType;
248     bool m_normalize;
249     int m_stride;
250     int m_offset;
251 };
252 
253 class ContextArrayPack
254 {
255 public:
256     ContextArrayPack(glu::RenderContext &renderCtx, sglr::Context &drawContext);
257     virtual ~ContextArrayPack(void);
258     virtual Array *getArray(int i);
259     virtual int getArrayCount(void);
260     virtual void newArray(Array::Storage storage);
261     virtual void render(Array::Primitive primitive, int firstVertex, int vertexCount, bool useVao, float coordScale,
262                         float colorScale);
263 
getSurface(void) const264     const tcu::Surface &getSurface(void) const
265     {
266         return m_screen;
267     }
268 
269 private:
270     void updateProgram(void);
271     glu::RenderContext &m_renderCtx;
272     sglr::Context &m_ctx;
273 
274     std::vector<ContextArray *> m_arrays;
275     sglr::ShaderProgram *m_program;
276     tcu::Surface m_screen;
277 };
278 
279 class GLValue
280 {
281 public:
282     template <class Type>
283     class WrappedType
284     {
285     public:
create(Type value)286         static WrappedType<Type> create(Type value)
287         {
288             WrappedType<Type> v;
289             v.m_value = value;
290             return v;
291         }
fromFloat(float value)292         static WrappedType<Type> fromFloat(float value)
293         {
294             WrappedType<Type> v;
295             v.m_value = (Type)value;
296             return v;
297         }
getValue(void) const298         inline Type getValue(void) const
299         {
300             return m_value;
301         }
302 
operator +(const WrappedType<Type> & other) const303         inline WrappedType<Type> operator+(const WrappedType<Type> &other) const
304         {
305             return WrappedType<Type>::create((Type)(m_value + other.getValue()));
306         }
operator *(const WrappedType<Type> & other) const307         inline WrappedType<Type> operator*(const WrappedType<Type> &other) const
308         {
309             return WrappedType<Type>::create((Type)(m_value * other.getValue()));
310         }
operator /(const WrappedType<Type> & other) const311         inline WrappedType<Type> operator/(const WrappedType<Type> &other) const
312         {
313             return WrappedType<Type>::create((Type)(m_value / other.getValue()));
314         }
operator %(const WrappedType<Type> & other) const315         inline WrappedType<Type> operator%(const WrappedType<Type> &other) const
316         {
317             return WrappedType<Type>::create((Type)(m_value % other.getValue()));
318         }
operator -(const WrappedType<Type> & other) const319         inline WrappedType<Type> operator-(const WrappedType<Type> &other) const
320         {
321             return WrappedType<Type>::create((Type)(m_value - other.getValue()));
322         }
323 
operator +=(const WrappedType<Type> & other)324         inline WrappedType<Type> &operator+=(const WrappedType<Type> &other)
325         {
326             m_value += other.getValue();
327             return *this;
328         }
operator *=(const WrappedType<Type> & other)329         inline WrappedType<Type> &operator*=(const WrappedType<Type> &other)
330         {
331             m_value *= other.getValue();
332             return *this;
333         }
operator /=(const WrappedType<Type> & other)334         inline WrappedType<Type> &operator/=(const WrappedType<Type> &other)
335         {
336             m_value /= other.getValue();
337             return *this;
338         }
operator -=(const WrappedType<Type> & other)339         inline WrappedType<Type> &operator-=(const WrappedType<Type> &other)
340         {
341             m_value -= other.getValue();
342             return *this;
343         }
344 
operator ==(const WrappedType<Type> & other) const345         inline bool operator==(const WrappedType<Type> &other) const
346         {
347             return m_value == other.m_value;
348         }
operator !=(const WrappedType<Type> & other) const349         inline bool operator!=(const WrappedType<Type> &other) const
350         {
351             return m_value != other.m_value;
352         }
operator <(const WrappedType<Type> & other) const353         inline bool operator<(const WrappedType<Type> &other) const
354         {
355             return m_value < other.m_value;
356         }
operator >(const WrappedType<Type> & other) const357         inline bool operator>(const WrappedType<Type> &other) const
358         {
359             return m_value > other.m_value;
360         }
operator <=(const WrappedType<Type> & other) const361         inline bool operator<=(const WrappedType<Type> &other) const
362         {
363             return m_value <= other.m_value;
364         }
operator >=(const WrappedType<Type> & other) const365         inline bool operator>=(const WrappedType<Type> &other) const
366         {
367             return m_value >= other.m_value;
368         }
369 
operator Type(void) const370         inline operator Type(void) const
371         {
372             return m_value;
373         }
374         template <class T>
to(void) const375         inline T to(void) const
376         {
377             return (T)m_value;
378         }
379 
380     private:
381         Type m_value;
382     };
383 
384     template <class Type>
385     class WrappedFloatType
386     {
387     public:
create(Type value)388         static WrappedFloatType<Type> create(Type value)
389         {
390             WrappedFloatType<Type> v;
391             v.m_value = value;
392             return v;
393         }
fromFloat(float value)394         static WrappedFloatType<Type> fromFloat(float value)
395         {
396             WrappedFloatType<Type> v;
397             v.m_value = (Type)value;
398             return v;
399         }
getValue(void) const400         inline Type getValue(void) const
401         {
402             return m_value;
403         }
404 
operator +(const WrappedFloatType<Type> & other) const405         inline WrappedFloatType<Type> operator+(const WrappedFloatType<Type> &other) const
406         {
407             return WrappedFloatType<Type>::create((Type)(m_value + other.getValue()));
408         }
operator *(const WrappedFloatType<Type> & other) const409         inline WrappedFloatType<Type> operator*(const WrappedFloatType<Type> &other) const
410         {
411             return WrappedFloatType<Type>::create((Type)(m_value * other.getValue()));
412         }
operator /(const WrappedFloatType<Type> & other) const413         inline WrappedFloatType<Type> operator/(const WrappedFloatType<Type> &other) const
414         {
415             return WrappedFloatType<Type>::create((Type)(m_value / other.getValue()));
416         }
operator %(const WrappedFloatType<Type> & other) const417         inline WrappedFloatType<Type> operator%(const WrappedFloatType<Type> &other) const
418         {
419             return WrappedFloatType<Type>::create((Type)(deMod(m_value, other.getValue())));
420         }
operator -(const WrappedFloatType<Type> & other) const421         inline WrappedFloatType<Type> operator-(const WrappedFloatType<Type> &other) const
422         {
423             return WrappedFloatType<Type>::create((Type)(m_value - other.getValue()));
424         }
425 
operator +=(const WrappedFloatType<Type> & other)426         inline WrappedFloatType<Type> &operator+=(const WrappedFloatType<Type> &other)
427         {
428             m_value += other.getValue();
429             return *this;
430         }
operator *=(const WrappedFloatType<Type> & other)431         inline WrappedFloatType<Type> &operator*=(const WrappedFloatType<Type> &other)
432         {
433             m_value *= other.getValue();
434             return *this;
435         }
operator /=(const WrappedFloatType<Type> & other)436         inline WrappedFloatType<Type> &operator/=(const WrappedFloatType<Type> &other)
437         {
438             m_value /= other.getValue();
439             return *this;
440         }
operator -=(const WrappedFloatType<Type> & other)441         inline WrappedFloatType<Type> &operator-=(const WrappedFloatType<Type> &other)
442         {
443             m_value -= other.getValue();
444             return *this;
445         }
446 
operator ==(const WrappedFloatType<Type> & other) const447         inline bool operator==(const WrappedFloatType<Type> &other) const
448         {
449             return m_value == other.m_value;
450         }
operator !=(const WrappedFloatType<Type> & other) const451         inline bool operator!=(const WrappedFloatType<Type> &other) const
452         {
453             return m_value != other.m_value;
454         }
operator <(const WrappedFloatType<Type> & other) const455         inline bool operator<(const WrappedFloatType<Type> &other) const
456         {
457             return m_value < other.m_value;
458         }
operator >(const WrappedFloatType<Type> & other) const459         inline bool operator>(const WrappedFloatType<Type> &other) const
460         {
461             return m_value > other.m_value;
462         }
operator <=(const WrappedFloatType<Type> & other) const463         inline bool operator<=(const WrappedFloatType<Type> &other) const
464         {
465             return m_value <= other.m_value;
466         }
operator >=(const WrappedFloatType<Type> & other) const467         inline bool operator>=(const WrappedFloatType<Type> &other) const
468         {
469             return m_value >= other.m_value;
470         }
471 
operator Type(void) const472         inline operator Type(void) const
473         {
474             return m_value;
475         }
476         template <class T>
to(void) const477         inline T to(void) const
478         {
479             return (T)m_value;
480         }
481 
482     private:
483         Type m_value;
484     };
485 
486     typedef WrappedType<int16_t> Short;
487     typedef WrappedType<uint16_t> Ushort;
488 
489     typedef WrappedType<int8_t> Byte;
490     typedef WrappedType<uint8_t> Ubyte;
491 
492     typedef WrappedFloatType<float> Float;
493     typedef WrappedFloatType<double> Double;
494 
495     typedef WrappedType<int32_t> Int;
496     typedef WrappedType<uint32_t> Uint;
497 
498     class Half
499     {
500     public:
create(float value)501         static Half create(float value)
502         {
503             Half h;
504             h.m_value = floatToHalf(value);
505             return h;
506         }
fromFloat(float value)507         static Half fromFloat(float value)
508         {
509             Half h;
510             h.m_value = floatToHalf(value);
511             return h;
512         }
getValue(void) const513         inline deFloat16 getValue(void) const
514         {
515             return m_value;
516         }
517 
operator +(const Half & other) const518         inline Half operator+(const Half &other) const
519         {
520             return create(halfToFloat(m_value) + halfToFloat(other.getValue()));
521         }
operator *(const Half & other) const522         inline Half operator*(const Half &other) const
523         {
524             return create(halfToFloat(m_value) * halfToFloat(other.getValue()));
525         }
operator /(const Half & other) const526         inline Half operator/(const Half &other) const
527         {
528             return create(halfToFloat(m_value) / halfToFloat(other.getValue()));
529         }
operator %(const Half & other) const530         inline Half operator%(const Half &other) const
531         {
532             return create(deFloatMod(halfToFloat(m_value), halfToFloat(other.getValue())));
533         }
operator -(const Half & other) const534         inline Half operator-(const Half &other) const
535         {
536             return create(halfToFloat(m_value) - halfToFloat(other.getValue()));
537         }
538 
operator +=(const Half & other)539         inline Half &operator+=(const Half &other)
540         {
541             m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value));
542             return *this;
543         }
operator *=(const Half & other)544         inline Half &operator*=(const Half &other)
545         {
546             m_value = floatToHalf(halfToFloat(other.getValue()) * halfToFloat(m_value));
547             return *this;
548         }
operator /=(const Half & other)549         inline Half &operator/=(const Half &other)
550         {
551             m_value = floatToHalf(halfToFloat(other.getValue()) / halfToFloat(m_value));
552             return *this;
553         }
operator -=(const Half & other)554         inline Half &operator-=(const Half &other)
555         {
556             m_value = floatToHalf(halfToFloat(other.getValue()) - halfToFloat(m_value));
557             return *this;
558         }
559 
operator ==(const Half & other) const560         inline bool operator==(const Half &other) const
561         {
562             return m_value == other.m_value;
563         }
operator !=(const Half & other) const564         inline bool operator!=(const Half &other) const
565         {
566             return m_value != other.m_value;
567         }
operator <(const Half & other) const568         inline bool operator<(const Half &other) const
569         {
570             return halfToFloat(m_value) < halfToFloat(other.m_value);
571         }
operator >(const Half & other) const572         inline bool operator>(const Half &other) const
573         {
574             return halfToFloat(m_value) > halfToFloat(other.m_value);
575         }
operator <=(const Half & other) const576         inline bool operator<=(const Half &other) const
577         {
578             return halfToFloat(m_value) <= halfToFloat(other.m_value);
579         }
operator >=(const Half & other) const580         inline bool operator>=(const Half &other) const
581         {
582             return halfToFloat(m_value) >= halfToFloat(other.m_value);
583         }
584 
585         template <class T>
to(void) const586         inline T to(void) const
587         {
588             return (T)halfToFloat(m_value);
589         }
590 
591         inline static deFloat16 floatToHalf(float f);
592         inline static float halfToFloat(deFloat16 h);
593 
594     private:
595         deFloat16 m_value;
596     };
597 
598     class Fixed
599     {
600     public:
create(int32_t value)601         static Fixed create(int32_t value)
602         {
603             Fixed v;
604             v.m_value = value;
605             return v;
606         }
fromFloat(float value)607         static Fixed fromFloat(float value)
608         {
609             Fixed v;
610             v.m_value = (int32_t)value;
611             return v;
612         }
getValue(void) const613         inline int32_t getValue(void) const
614         {
615             return m_value;
616         }
617 
operator +(const Fixed & other) const618         inline Fixed operator+(const Fixed &other) const
619         {
620             return create(m_value + other.getValue());
621         }
operator *(const Fixed & other) const622         inline Fixed operator*(const Fixed &other) const
623         {
624             return create(m_value * other.getValue());
625         }
operator /(const Fixed & other) const626         inline Fixed operator/(const Fixed &other) const
627         {
628             return create(m_value / other.getValue());
629         }
operator %(const Fixed & other) const630         inline Fixed operator%(const Fixed &other) const
631         {
632             return create(m_value % other.getValue());
633         }
operator -(const Fixed & other) const634         inline Fixed operator-(const Fixed &other) const
635         {
636             return create(m_value - other.getValue());
637         }
638 
operator +=(const Fixed & other)639         inline Fixed &operator+=(const Fixed &other)
640         {
641             m_value += other.getValue();
642             return *this;
643         }
operator *=(const Fixed & other)644         inline Fixed &operator*=(const Fixed &other)
645         {
646             m_value *= other.getValue();
647             return *this;
648         }
operator /=(const Fixed & other)649         inline Fixed &operator/=(const Fixed &other)
650         {
651             m_value /= other.getValue();
652             return *this;
653         }
operator -=(const Fixed & other)654         inline Fixed &operator-=(const Fixed &other)
655         {
656             m_value -= other.getValue();
657             return *this;
658         }
659 
operator ==(const Fixed & other) const660         inline bool operator==(const Fixed &other) const
661         {
662             return m_value == other.m_value;
663         }
operator !=(const Fixed & other) const664         inline bool operator!=(const Fixed &other) const
665         {
666             return m_value != other.m_value;
667         }
operator <(const Fixed & other) const668         inline bool operator<(const Fixed &other) const
669         {
670             return m_value < other.m_value;
671         }
operator >(const Fixed & other) const672         inline bool operator>(const Fixed &other) const
673         {
674             return m_value > other.m_value;
675         }
operator <=(const Fixed & other) const676         inline bool operator<=(const Fixed &other) const
677         {
678             return m_value <= other.m_value;
679         }
operator >=(const Fixed & other) const680         inline bool operator>=(const Fixed &other) const
681         {
682             return m_value >= other.m_value;
683         }
684 
operator int32_t(void) const685         inline operator int32_t(void) const
686         {
687             return m_value;
688         }
689         template <class T>
to(void) const690         inline T to(void) const
691         {
692             return (T)m_value;
693         }
694 
695     private:
696         int32_t m_value;
697     };
698 
699     // \todo [mika] This is pretty messy
GLValue(void)700     GLValue(void) : type(Array::INPUTTYPE_LAST)
701     {
702     }
GLValue(Float value)703     explicit GLValue(Float value) : type(Array::INPUTTYPE_FLOAT), fl(value)
704     {
705     }
GLValue(Fixed value)706     explicit GLValue(Fixed value) : type(Array::INPUTTYPE_FIXED), fi(value)
707     {
708     }
GLValue(Byte value)709     explicit GLValue(Byte value) : type(Array::INPUTTYPE_BYTE), b(value)
710     {
711     }
GLValue(Ubyte value)712     explicit GLValue(Ubyte value) : type(Array::INPUTTYPE_UNSIGNED_BYTE), ub(value)
713     {
714     }
GLValue(Short value)715     explicit GLValue(Short value) : type(Array::INPUTTYPE_SHORT), s(value)
716     {
717     }
GLValue(Ushort value)718     explicit GLValue(Ushort value) : type(Array::INPUTTYPE_UNSIGNED_SHORT), us(value)
719     {
720     }
GLValue(Int value)721     explicit GLValue(Int value) : type(Array::INPUTTYPE_INT), i(value)
722     {
723     }
GLValue(Uint value)724     explicit GLValue(Uint value) : type(Array::INPUTTYPE_UNSIGNED_INT), ui(value)
725     {
726     }
GLValue(Half value)727     explicit GLValue(Half value) : type(Array::INPUTTYPE_HALF), h(value)
728     {
729     }
GLValue(Double value)730     explicit GLValue(Double value) : type(Array::INPUTTYPE_DOUBLE), d(value)
731     {
732     }
733 
734     float toFloat(void) const;
735 
736     static GLValue getMaxValue(Array::InputType type);
737     static GLValue getMinValue(Array::InputType type);
738 
739     Array::InputType type;
740 
741     union
742     {
743         Float fl;
744         Fixed fi;
745         Double d;
746         Byte b;
747         Ubyte ub;
748         Short s;
749         Ushort us;
750         Int i;
751         Uint ui;
752         Half h;
753     };
754 };
755 
756 class VertexArrayTest : public tcu::TestCase
757 {
758 public:
759     VertexArrayTest(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name, const char *desc);
760     virtual ~VertexArrayTest(void);
761     virtual void init(void);
762     virtual void deinit(void);
763 
764 protected:
765     VertexArrayTest(const VertexArrayTest &other);
766     VertexArrayTest &operator=(const VertexArrayTest &other);
767 
768     void compare(void);
769 
770     glu::RenderContext &m_renderCtx;
771 
772     sglr::ReferenceContextBuffers *m_refBuffers;
773     sglr::ReferenceContext *m_refContext;
774     sglr::Context *m_glesContext;
775 
776     ContextArrayPack *m_glArrayPack;
777     ContextArrayPack *m_rrArrayPack;
778     bool m_isOk;
779 
780     int m_maxDiffRed;
781     int m_maxDiffGreen;
782     int m_maxDiffBlue;
783 };
784 
785 class MultiVertexArrayTest : public VertexArrayTest
786 {
787 public:
788     class Spec
789     {
790     public:
791         class ArraySpec
792         {
793         public:
794             ArraySpec(Array::InputType inputType, Array::OutputType outputType, Array::Storage storage,
795                       Array::Usage usage, int componetCount, int offset, int stride, bool normalize, GLValue min,
796                       GLValue max);
797 
798             Array::InputType inputType;
799             Array::OutputType outputType;
800             Array::Storage storage;
801             Array::Usage usage;
802             int componentCount;
803             int offset;
804             int stride;
805             bool normalize;
806             GLValue min;
807             GLValue max;
808         };
809 
810         std::string getName(void) const;
811         std::string getDesc(void) const;
812 
813         Array::Primitive primitive;
814         int drawCount; //!<Number of primitives to draw
815         int first;
816 
817         std::vector<ArraySpec> arrays;
818     };
819 
820     MultiVertexArrayTest(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const Spec &spec, const char *name,
821                          const char *desc);
822     virtual ~MultiVertexArrayTest(void);
823     virtual IterateResult iterate(void);
824 
825 private:
826     bool isUnalignedBufferOffsetTest(void) const;
827     bool isUnalignedBufferStrideTest(void) const;
828 
829     Spec m_spec;
830     int m_iteration;
831 };
832 
floatToHalf(float f)833 inline deFloat16 GLValue::Half::floatToHalf(float f)
834 {
835     // No denorm support.
836     tcu::Float<uint16_t, 5, 10, 15, tcu::FLOAT_HAS_SIGN> v(f);
837     DE_ASSERT(!v.isNaN() && !v.isInf());
838     return v.bits();
839 }
840 
halfToFloat(deFloat16 h)841 inline float GLValue::Half::halfToFloat(deFloat16 h)
842 {
843     return tcu::Float16((uint16_t)h).asFloat();
844 }
845 
846 } // namespace gls
847 } // namespace deqp
848 
849 #endif // _GLSVERTEXARRAYTESTS_HPP
850