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