1 #ifndef _GLSVERTEXARRAYTESTS_HPP
2 #define _GLSVERTEXARRAYTESTS_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements Quality Program OpenGL (ES) Module
5 * -----------------------------------------------
7 * Copyright 2014 The Android Open Source Project
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 * \brief Vertex array and buffer tests
24 *//*--------------------------------------------------------------------*/
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 "tcuFloat.hpp"
35 #include "tcuPixelFormat.hpp"
36 #include "sglrContext.hpp"
41 class ReferenceContextBuffers;
42 class ReferenceContext;
57 // \note [mika] Are these actualy used somewhere?
58 TARGET_ELEMENT_ARRAY = 0,
73 INPUTTYPE_UNSIGNED_BYTE,
74 INPUTTYPE_UNSIGNED_SHORT,
77 INPUTTYPE_UNSIGNED_INT,
79 INPUTTYPE_UNSIGNED_INT_2_10_10_10,
80 INPUTTYPE_INT_2_10_10_10,
108 USAGE_DYNAMIC_DRAW = 0,
134 PRIMITIVE_POINTS = 0,
136 PRIMITIVE_TRIANGLE_FAN,
137 PRIMITIVE_TRIANGLE_STRIP,
142 static std::string targetToString (Target target);
143 static std::string inputTypeToString (InputType type);
144 static std::string outputTypeToString (OutputType type);
145 static std::string usageTypeToString (Usage usage);
146 static std::string storageToString (Storage storage);
147 static std::string primitiveToString (Primitive primitive);
148 static int inputTypeSize (InputType type);
150 virtual ~Array (void) {}
151 virtual void data (Target target, int size, const char* data, Usage usage) = 0;
152 virtual void subdata (Target target, int offset, int size, const char* data) = 0;
153 virtual void bind (int attribNdx, int offset, int size, InputType inType, OutputType outType, bool normalized, int stride) = 0;
154 virtual void unBind (void) = 0;
156 virtual bool isBound (void) const = 0;
157 virtual int getComponentCount (void) const = 0;
158 virtual Target getTarget (void) const = 0;
159 virtual InputType getInputType (void) const = 0;
160 virtual OutputType getOutputType (void) const = 0;
161 virtual Storage getStorageType (void) const = 0;
162 virtual bool getNormalized (void) const = 0;
163 virtual int getStride (void) const = 0;
164 virtual int getAttribNdx (void) const = 0;
165 virtual void setAttribNdx (int attribNdx) = 0;
168 class ContextArray : public Array
171 ContextArray (Storage storage, sglr::Context& context);
172 virtual ~ContextArray (void);
173 virtual void data (Target target, int size, const char* data, Usage usage);
174 virtual void subdata (Target target, int offset, int size, const char* data);
175 virtual void bind (int attribNdx, int offset, int size, InputType inType, OutputType outType, bool normalized, int stride);
176 virtual void bindIndexArray (Array::Target storage);
177 virtual void unBind (void) { m_bound = false; }
178 virtual bool isBound (void) const { return m_bound; }
180 virtual int getComponentCount (void) const { return m_componentCount; }
181 virtual Array::Target getTarget (void) const { return m_target; }
182 virtual Array::InputType getInputType (void) const { return m_inputType; }
183 virtual Array::OutputType getOutputType (void) const { return m_outputType; }
184 virtual Array::Storage getStorageType (void) const { return m_storage; }
185 virtual bool getNormalized (void) const { return m_normalize; }
186 virtual int getStride (void) const { return m_stride; }
187 virtual int getAttribNdx (void) const { return m_attribNdx; }
188 virtual void setAttribNdx (int attribNdx) { m_attribNdx = attribNdx; }
190 void glBind (deUint32 loc);
191 static deUint32 targetToGL (Array::Target target);
192 static deUint32 usageToGL (Array::Usage usage);
193 static deUint32 inputTypeToGL (Array::InputType type);
194 static std::string outputTypeToGLType (Array::OutputType type);
195 static deUint32 primitiveToGL (Array::Primitive primitive);
199 sglr::Context& m_ctx;
206 int m_componentCount;
207 Array::Target m_target;
208 Array::InputType m_inputType;
209 Array::OutputType m_outputType;
215 class ContextArrayPack
218 ContextArrayPack (glu::RenderContext& renderCtx, sglr::Context& drawContext);
219 virtual ~ContextArrayPack (void);
220 virtual Array* getArray (int i);
221 virtual int getArrayCount (void);
222 virtual void newArray (Array::Storage storage);
223 virtual void render (Array::Primitive primitive, int firstVertex, int vertexCount, bool useVao, float coordScale, float colorScale);
225 const tcu::Surface& getSurface (void) const { return m_screen; }
227 void updateProgram (void);
228 glu::RenderContext& m_renderCtx;
229 sglr::Context& m_ctx;
231 std::vector<ContextArray*> m_arrays;
232 sglr::ShaderProgram* m_program;
233 tcu::Surface m_screen;
244 static WrappedType<Type> create (Type value) { WrappedType<Type> v; v.m_value = value; return v; }
245 inline Type getValue (void) const { return m_value; }
247 inline WrappedType<Type> operator+ (const WrappedType<Type>& other) const { return WrappedType<Type>::create(m_value + other.getValue()); }
248 inline WrappedType<Type> operator* (const WrappedType<Type>& other) const { return WrappedType<Type>::create(m_value * other.getValue()); }
249 inline WrappedType<Type> operator/ (const WrappedType<Type>& other) const { return WrappedType<Type>::create(m_value / other.getValue()); }
250 inline WrappedType<Type> operator- (const WrappedType<Type>& other) const { return WrappedType<Type>::create(m_value - other.getValue()); }
252 inline WrappedType<Type>& operator+= (const WrappedType<Type>& other) { m_value += other.getValue(); return *this; }
253 inline WrappedType<Type>& operator*= (const WrappedType<Type>& other) { m_value *= other.getValue(); return *this; }
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; }
257 inline bool operator== (const WrappedType<Type>& other) const { return m_value == other.m_value; }
258 inline bool operator!= (const WrappedType<Type>& other) const { return m_value != other.m_value; }
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; }
264 inline operator Type (void) const { return m_value; }
266 inline T to (void) const { return (T)m_value; }
271 typedef WrappedType<deInt16> Short;
272 typedef WrappedType<deUint16> Ushort;
274 typedef WrappedType<deInt8> Byte;
275 typedef WrappedType<deUint8> Ubyte;
277 typedef WrappedType<float> Float;
278 typedef WrappedType<double> Double;
280 typedef WrappedType<deInt32> Int;
281 typedef WrappedType<deUint32> Uint;
286 static Half create (float value) { Half h; h.m_value = floatToHalf(value); return h; }
287 inline deFloat16 getValue (void) const { return m_value; }
289 inline Half operator+ (const Half& other) const { return create(halfToFloat(m_value) + halfToFloat(other.getValue())); }
290 inline Half operator* (const Half& other) const { return create(halfToFloat(m_value) * halfToFloat(other.getValue())); }
291 inline Half operator/ (const Half& other) const { return create(halfToFloat(m_value) / halfToFloat(other.getValue())); }
292 inline Half operator- (const Half& other) const { return create(halfToFloat(m_value) - halfToFloat(other.getValue())); }
294 inline Half& operator+= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value)); return *this; }
295 inline Half& operator*= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) * halfToFloat(m_value)); return *this; }
296 inline Half& operator/= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) / halfToFloat(m_value)); return *this; }
297 inline Half& operator-= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) - halfToFloat(m_value)); return *this; }
299 inline bool operator== (const Half& other) const { return m_value == other.m_value; }
300 inline bool operator!= (const Half& other) const { return m_value != other.m_value; }
301 inline bool operator< (const Half& other) const { return halfToFloat(m_value) < halfToFloat(other.m_value); }
302 inline bool operator> (const Half& other) const { return halfToFloat(m_value) > halfToFloat(other.m_value); }
303 inline bool operator<= (const Half& other) const { return halfToFloat(m_value) <= halfToFloat(other.m_value); }
304 inline bool operator>= (const Half& other) const { return halfToFloat(m_value) >= halfToFloat(other.m_value); }
307 inline T to (void) const { return (T)halfToFloat(m_value); }
309 inline static deFloat16 floatToHalf (float f);
310 inline static float halfToFloat (deFloat16 h);
318 static Fixed create (deInt32 value) { Fixed v; v.m_value = value; return v; }
319 inline deInt32 getValue (void) const { return m_value; }
321 inline Fixed operator+ (const Fixed& other) const { return create(m_value + other.getValue()); }
322 inline Fixed operator* (const Fixed& other) const { return create(m_value * other.getValue()); }
323 inline Fixed operator/ (const Fixed& other) const { return create(m_value / other.getValue()); }
324 inline Fixed operator- (const Fixed& other) const { return create(m_value - other.getValue()); }
326 inline Fixed& operator+= (const Fixed& other) { m_value += other.getValue(); return *this; }
327 inline Fixed& operator*= (const Fixed& other) { m_value *= other.getValue(); return *this; }
328 inline Fixed& operator/= (const Fixed& other) { m_value /= other.getValue(); return *this; }
329 inline Fixed& operator-= (const Fixed& other) { m_value -= other.getValue(); return *this; }
331 inline bool operator== (const Fixed& other) const { return m_value == other.m_value; }
332 inline bool operator!= (const Fixed& other) const { return m_value != other.m_value; }
333 inline bool operator< (const Fixed& other) const { return m_value < other.m_value; }
334 inline bool operator> (const Fixed& other) const { return m_value > other.m_value; }
335 inline bool operator<= (const Fixed& other) const { return m_value <= other.m_value; }
336 inline bool operator>= (const Fixed& other) const { return m_value >= other.m_value; }
338 inline operator deInt32 (void) const { return m_value; }
340 inline T to (void) const { return (T)m_value; }
345 // \todo [mika] This is pretty messy
346 GLValue (void) : type(Array::INPUTTYPE_LAST) {}
347 explicit GLValue (Float value) : type(Array::INPUTTYPE_FLOAT), fl(value) {}
348 explicit GLValue (Fixed value) : type(Array::INPUTTYPE_FIXED), fi(value) {}
349 explicit GLValue (Byte value) : type(Array::INPUTTYPE_BYTE), b(value) {}
350 explicit GLValue (Ubyte value) : type(Array::INPUTTYPE_UNSIGNED_BYTE), ub(value) {}
351 explicit GLValue (Short value) : type(Array::INPUTTYPE_SHORT), s(value) {}
352 explicit GLValue (Ushort value) : type(Array::INPUTTYPE_UNSIGNED_SHORT), us(value) {}
353 explicit GLValue (Int value) : type(Array::INPUTTYPE_INT), i(value) {}
354 explicit GLValue (Uint value) : type(Array::INPUTTYPE_UNSIGNED_INT), ui(value) {}
355 explicit GLValue (Half value) : type(Array::INPUTTYPE_HALF), h(value) {}
356 explicit GLValue (Double value) : type(Array::INPUTTYPE_DOUBLE), d(value) {}
358 float toFloat (void) const;
360 static GLValue getMaxValue (Array::InputType type);
361 static GLValue getMinValue (Array::InputType type);
363 Array::InputType type;
380 class VertexArrayTest : public tcu::TestCase
383 VertexArrayTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name ,const char* desc);
384 virtual ~VertexArrayTest (void);
385 virtual void init (void);
386 virtual void deinit (void);
389 VertexArrayTest (const VertexArrayTest& other);
390 VertexArrayTest& operator= (const VertexArrayTest& other);
394 glu::RenderContext& m_renderCtx;
396 sglr::ReferenceContextBuffers* m_refBuffers;
397 sglr::ReferenceContext* m_refContext;
398 sglr::Context* m_glesContext;
400 ContextArrayPack* m_glArrayPack;
401 ContextArrayPack* m_rrArrayPack;
409 class MultiVertexArrayTest : public VertexArrayTest
418 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);
420 Array::InputType inputType;
421 Array::OutputType outputType;
422 Array::Storage storage;
432 std::string getName (void) const;
433 std::string getDesc (void) const;
435 Array::Primitive primitive;
436 int drawCount; //!<Number of primitives to draw
439 std::vector<ArraySpec> arrays;
442 MultiVertexArrayTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const Spec& spec, const char* name, const char* desc);
443 virtual ~MultiVertexArrayTest (void);
444 virtual IterateResult iterate (void);
447 bool isUnalignedBufferOffsetTest (void) const;
448 bool isUnalignedBufferStrideTest (void) const;
454 inline deFloat16 GLValue::Half::floatToHalf (float f)
456 // No denorm support.
457 tcu::Float<deUint16, 5, 10, 15, tcu::FLOAT_HAS_SIGN> v(f);
458 DE_ASSERT(!v.isNaN() && !v.isInf());
462 inline float GLValue::Half::halfToFloat (deFloat16 h)
464 return tcu::Float16((deUint16)h).asFloat();
470 #endif // _GLSVERTEXARRAYTESTS_HPP